Java使用Aspose.word单个或批量导出word
在开发过程中,我们多数都会导入导出一些数据,其中excel表格占比较大,其次还有一些word导出,但是word导出过程中可能就涉及到一些word的排版,希望导出的word能前后左右都有格式设置。例如导出简历就需要排版,所以模板化导出就有了。
Aspose介绍
aspose有很多种功能,对不同的编程语言都有支持,有专门的网站,有兴趣的可以百度,链接:https://docs.aspose.com。在应用中,第一步需要引入相关的依赖,配置引入即可,有了这个我们就可以把渲染的页面以word的形式导出。
Freemarker介绍
freemarker是一种模板引擎,早期前后端不分离的情况,可以用来做前台页面。它主要定义好页面排版,后端生成数据填充进去,再进行渲染,从而呈现出来。
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
导出步骤及流程
首先我们新建一个导出接口,如下:
@PostMapping("/export")
public void export(HttpServletResponse response, @RequestBody ExportParam param) {
exportService.export(response, param);
}
新建导出的接口以及实现
@Override
public void export(HttpServletResponse response, ExportParam param) {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ServletOutputStream servletOutputStream = response.getOutputStream()) {
// 创建一个Configuration对象,直接new一个对象。构造方法的参数就是freemarker对于的版本号。
Configuration configuration = new Configuration(Configuration.getVersion());
// 设置模板文件所在的路径(一般放在resources下面子目录里)
configuration.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "/template/"));
// 设置模板文件使用的字符集,与模板里charset相同,不然会乱码
configuration.setDefaultEncoding("utf-8");
// 加载一个模板,创建一个模板对象。
Template template = configuration.getTemplate("/jianli.ftl");
// 创建一个模板使用的数据集,可以是pojo也可以是map。一般是Map。
Map<String, Object> dataModel = new HashMap<>();
....
//todo 向数据集中添加数据,根据入参查询出相关数据,放入dataModel中
// dataModel.put("data", 查询的数据);
....
// 创建一个Writer对象,一般创建一FileWriter对象,指定生成的文件名。
Writer out = new StringWriter();
// 调用模板对象的process方法输出文件。
template.process(dataModel, out);
// 关闭流。
Document document = new Document();
DocumentBuilder builder = new DocumentBuilder(document);
builder.insertHtml(out.toString());
document.save(outputStream, SaveFormat.DOCX);
// 将文档作为响应返回到前端
byte[] documentBytes = outputStream.toByteArray();
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setHeader("Content-Disposition", "attachment; filename=d.docx");
response.setContentLength(documentBytes.length);
servletOutputStream.write(documentBytes);
} catch (Exception e) {
log.error("导出异常", e);
throw new Exception("导出异常!");
}
}
这就是整个导出流程所需的代码,然而在导出的时候你会发现你的文档被打上水印了,网上搜了下有一些破解的例子,有需要的可以自行了解,留言私信,这里不展示了。到此为止Java代码模块就结束了,细致点就在freemarker的编写上了,这个模板的编写可能需要前端同学帮忙,用样式美化页面。下面例举一些freemarker用法,当然可自行百度相关
<#assign alphabetMap = ['1', '2', 'C']> #定义一个集合
<#assign object = {'1':'A', '2':'b', 'C':'r'}> #定义对象
<#assign single= 222> #定义单个值
${data.field} #获取后台传递的data中的field字段值
<#list items as item > #循环items集合
<#if item.type=="1"> #判断item的type字段值
·····
<#elseif item.type=='2'>
····
<#else>
·····
</#if>
${item_index} #获取当前item所在集合的下标
<#assign options = item.experience?eval_json /> #将item中experience字符串json格式化
</#list>
如下简历jianli.ftl中一部分:
<body class='typora-export os-windows'>
<div class='typora-export-content'>
<div id='write' class=''>
<p>
<span> </span>
<span>个人简历</span>
</p>
<p>
<span>姓名:${data.name}</span>
</p>
<p>
<span>经历:</span>
</p>
<#assign items= data.experience?eval_json />
<#list items as item >
<p>
<span>${item_index+1}.${item.projectName}</span>
<span>${item.projectDes}</span>
</p>
</#list>
</div>
</div>
</body>
批量导出,将多个word文档添加到一个压缩包中一起导出
@Override
public void exportAllExamContent(HttpServletResponse response, List<ExportParam> params) {
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
response.reset();
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=a.zip");
//查询要导出的列表
for (ExportParam param : params) {
//todo 业务数据查询data
outputStream.reset();
byte[] documentBytes = getBytes(data, outputStream);//这里可以结合单个导出的方法将数据转为byte数组,然后写入ZipOutputStream
zos.putNextEntry(new ZipEntry(param.getName() + ".docx"));
zos.write(documentBytes);
zos.closeEntry();
}
} catch (Exception e) {
log.error("批量导出异常", e);
throw new Exception("导出异常!");
}
}
总结
整个导出过程就是使用html编写一个格式化的word页面,我们需要的word文档什么样子,html就编写成什么样,然后再用freemarker将其中需要根据后台数据变化的地方通过freemarker的语法通过后台传递的值动态获取加载渲染出来,最后使用Aspose.word将html转化导出成word。