Java實(shí)現(xiàn)動(dòng)態(tài)生成word報(bào)告
1.準(zhǔn)備好docx文件模板
舉例:動(dòng)態(tài)生成表格數(shù)據(jù),以下是list數(shù)組類型的freemarker語法
將寫好的word模板加入到templates目錄下
2.在pom.xml中導(dǎo)入相關(guān)依賴
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.1</version>
</dependency>
3.關(guān)于Minio的介紹
Minio 是一個(gè)開源的對象存儲(chǔ)服務(wù)器,可用于存儲(chǔ)和訪問海量數(shù)據(jù)。以下是 Minio 的基本用法:
(1)安裝 Minio
首先,你需要下載和安裝 Minio。你可以從 Minio 的官方網(wǎng)站(https://min.io/)下載適用于你的操作系統(tǒng)的安裝包,然后按照 Minio 的安裝說明進(jìn)行操作。
(2)啟動(dòng) Minio
安裝完成后,你可以通過運(yùn)行以下命令來啟動(dòng) Minio:
bash復(fù)制代碼
minio server /path/to/data
其中 /path/to/data
是你用于存儲(chǔ)數(shù)據(jù)的目錄或磁盤空間。
(3)訪問 Minio
一旦 Minio 啟動(dòng)成功,你就可以使用 Web 瀏覽器、命令行工具或 SDK 來訪問和操作 Minio。文章來源:http://www.zghlxwxcb.cn/news/detail-493108.html
- Web 瀏覽器:在瀏覽器中輸入 Minio 的訪問地址(默認(rèn)為
localhost:9000
),即可看到 Minio 的管理界面。你可以使用默認(rèn)的用戶名和密碼(分別為minio
和minio123
)登錄。 - 命令行工具:你可以使用 Minio 提供的命令行工具(如
mc
或bs
)來訪問和操作 Minio。這些工具提供了豐富的命令行選項(xiàng)和 SDK,方便你進(jìn)行數(shù)據(jù)的上傳、下載、備份、恢復(fù)等操作。 - SDK:Minio 還提供了多種編程語言的 SDK,如 Java、Python、Go、JavaScript 等。你可以使用這些 SDK 在應(yīng)用程序中集成 Minio 的功能,以便更方便地管理和操作數(shù)據(jù)。
總之,使用 Minio 可以通過簡單的安裝和配置,快速構(gòu)建一個(gè)可靠的對象存儲(chǔ)服務(wù),方便你存儲(chǔ)和訪問海量數(shù)據(jù)。文章來源地址http://www.zghlxwxcb.cn/news/detail-493108.html
4.在application.yml中添加Minio配置
minio:
//host和port自行填寫
endpoint: http://127.0.0.1:9000
accessKey: minio
secretKey: minio123
bucketName: carbon
expires: 86400
5.導(dǎo)入MinioConfig配置類
@Data
@Configuration
public class MinioConfig {
@Value("${minio.endpoint}")
private String endpoint;
@Value("${minio.bucketName}")
private String bucketName;
@Value("${minio.accessKey}")
private String accessKey;
@Value("${minio.secretKey}")
private String secretKey;
@Value("${minio.expires}")
private Integer expires = 86400;
}
6.導(dǎo)入U(xiǎn)ploadFileService類與其實(shí)現(xiàn)類UploadFileServiceImpl(直接CV過去)
public interface UploadFileService {
void createBucket(String bucketName);
/**
* 獲取全部bucket
* <p>
* https://docs.minio.io/cn/java-client-api-reference.html#listBuckets
*/
List<Bucket> getAllBuckets();
/**
* 根據(jù)bucketName獲取信息
*
* @param bucketName bucket名稱
*/
// @SneakyThrows
Optional<Bucket> getBucket(String bucketName);
/**
* 根據(jù)bucketName刪除信息
*
* @param bucketName bucket名稱
*/
void removeBucket(String bucketName);
/**
* 根據(jù)文件前置查詢文件
*
* @param bucketName bucket名稱
* @param prefix 前綴
* @param recursive 是否遞歸查詢
* @return MinioItem 列表
*/
List getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive);
/**
* 獲取文件外鏈
*
* @param bucketName bucket名稱
* @param objectName 文件名稱
* @param expires 過期時(shí)間 <=7
* @return url
*/
String getObjectURL(String bucketName, String objectName, Integer expires);
/**
* 獲取文件
*
* @param bucketName bucket名稱
* @param objectName 文件名稱
* @return 二進(jìn)制流
*/
InputStream getObject(String bucketName, String objectName);
/**
* 上傳文件
*
* @param bucketName bucket名稱
* @param stream 文件流
* @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
*/
void putObject(String bucketName, String objectName, InputStream stream);
/**
* 上傳文件
*
* @param bucketName bucket名稱
* @param objectName 文件名稱
* @param stream 文件流
* @param size 大小
* @param contextType 類型
* @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
*/
void putObject(String bucketName, String objectName, InputStream stream, long size, String contextType);
/**
* 獲取文件信息, 如果拋出異常則說明文件不存在
*
* @param bucketName bucket名稱
* @param objectName 文件名稱
* @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#statObject
*/
StatObjectResponse getObjectInfo(String bucketName, String objectName);
/**
* 刪除文件
*
* @param bucketName bucket名稱
* @param objectName 文件名稱
* @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeObject
*/
boolean removeObject(String bucketName, String objectName) throws Exception;
}
@Slf4j
@Service
public class UploadFileServiceImpl implements UploadFileService {
private MinioClient minioClient;
@Autowired
MinioConfig minioConfig;
@PostConstruct
public void init() {
this.minioClient =
MinioClient.builder()
.endpoint(minioConfig.getEndpoint())
.credentials(minioConfig.getAccessKey(), minioConfig.getSecretKey())
.build();
}
@Override
@SneakyThrows
public void createBucket(String bucketName) {
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
}
@Override
@SneakyThrows
public List<Bucket> getAllBuckets() {
// 列出所有存儲(chǔ)桶
return minioClient.listBuckets();
}
@Override
@SneakyThrows
public Optional<Bucket> getBucket(String bucketName) {
return minioClient.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
}
@Override
@SneakyThrows
public void removeBucket(String bucketName) {
// 刪除之前先檢查bucketName是否存在。
boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
if (found) {
// 刪除bucketName存儲(chǔ)桶,注意,只有存儲(chǔ)桶為空時(shí)才能刪除成功。
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
} else {
log.info(bucketName + "does not exist");
}
}
@Override
@SneakyThrows
public List getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) {
List<Item> list = new ArrayList<>();
Iterable<Result<Item>> objectsIterator = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucketName).prefix(prefix)
.recursive(recursive).build()
);
if (objectsIterator != null) {
Iterator<Result<Item>> iterator = objectsIterator.iterator();
if (iterator != null) {
while (iterator.hasNext()) {
Result<Item> result = iterator.next();
Item item = result.get();
list.add(item);
}
}
}
return list;
}
@Override
@SneakyThrows
public String getObjectURL(String bucketName, String objectName, Integer expires) {
return minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucketName)
.object(objectName)
.expiry(expires, TimeUnit.DAYS)
.build());
}
@Override
@SneakyThrows
public InputStream getObject(String bucketName, String objectName) {
return minioClient.getObject(GetObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build());
}
@Override
@SneakyThrows
public void putObject(String bucketName, String objectName, InputStream stream) {
// 檢查存儲(chǔ)桶是否已經(jīng)存在
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
minioClient.putObject(
PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(
stream, stream.available(), -1)
.build());
}
@Override
@SneakyThrows
public void putObject(String bucketName, String objectName, InputStream stream, long size, String contextType) {
minioClient.putObject(
PutObjectArgs.builder().bucket(bucketName)
.object(objectName).stream(stream, size, -1)
.contentType(contextType).build());
}
@Override
@SneakyThrows
public StatObjectResponse getObjectInfo(String bucketName, String objectName) {
StatObjectResponse statObjectResponse = minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
return statObjectResponse;
}
@Override
public boolean removeObject(String bucketName, String objectName) throws Exception {
try {
minioClient.removeObject(
RemoveObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build());
} catch (Exception e) {
return false;
}
return true;
}
}
7.編寫ReportData類
@Slf4j
@Data
@Component
public class ReportData {
//generateReport可加入需要的參數(shù)
public String generateReport() throws IOException, XDocReportException {
//通過freemarker模板引擎加載文檔,并緩存到registry中
ClassPathResource resource= new ClassPathResource("templates/report.docx");
InputStream input = resource.getInputStream();
IXDocReport report = XDocReportRegistry
.getRegistry()
.loadReport(input, TemplateEngineKind.Freemarker);
//匹配填充字段和填充數(shù)據(jù),進(jìn)行填充
IContext context = report.createContext();
//獲取要放入報(bào)告的數(shù)據(jù)(省略),假設(shè)獲取到了一個(gè)list數(shù)組dataList
//context.put(" ", )放入相應(yīng)的數(shù)據(jù),可在word模板中動(dòng)態(tài)調(diào)用
context.put("time", LocalDateTime.now());
context.put("dataList",dataList);
ByteArrayOutputStream output = new ByteArrayOutputStream();
report.process(context, output);
ByteArrayInputStream inputStream = new ByteArrayInputStream(output.toByteArray());
String objectName = "Document/"+"報(bào)告.docx";
uploadFileService.putObject(minioConfig.getBucketName(),objectName, inputStream);
return objectName;
}
}
8.controller層調(diào)用
@RequestMapping(value = "/reportExport", method = RequestMethod.POST)
//UserServiceByReportExport中可填寫所需參數(shù)
public void UserServiceByReportExport(HttpServletRequest request, HttpServletResponse response) throws IOException, XDocReportException {
// TODO 使用預(yù)置的word文檔導(dǎo)出
String objectName = reportData.generateReport();
Optional<InputStream> inputOp = Optional.of(uploadFileService.getObject(minioConfig.getBucketName(), objectName));
if (!inputOp.isPresent()) {
throw new NullPointerException("報(bào)告生成失敗");
}
try (InputStream input1 = inputOp.get();
OutputStream output1 = response.getOutputStream()) {
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.addHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode( "報(bào)告.docx", "UTF-8"));
response.setHeader("Access-Control-Expose-Headers","Content-Disposition");
IoUtils.copy(input1, output1);
} catch (Exception e) {
e.printStackTrace();
}
}
到了這里,關(guān)于Java實(shí)現(xiàn)動(dòng)態(tài)生成word報(bào)告的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!