生命无罪,健康万岁,我是laity。
我曾七次鄙视自己的灵魂:
第一次,当它本可进取时,却故作谦卑;
第二次,当它在空虚时,用爱欲来填充;
第三次,在困难和容易之间,它选择了容易;
第四次,它犯了错,却借由别人也会犯错来宽慰自己;
第五次,它自由软弱,却把它认为是生命的坚韧;
第六次,当它鄙夷一张丑恶的嘴脸时,却不知那正是自己面具中的一副;
第七次,它侧身于生活的污泥中,虽不甘心,却又畏首畏尾。
动态数据生成word报表
,其实是前端的活(前端做简单),如果这个活现在担任在"各位"后端身上,就希望本文能够给予你一定的帮助吧!
Java操作Word
方案一
使用easypoi + jfree
操作比较简单,如果你的报表生成也简单的情况推荐使用;
有需要的小伙伴可以直接看Java生成Word
问题
- 这个是比较好实现的,但easypoi问题太多,而且版本兼容性差的很;
- 有兴趣的小伙伴可以去看开源仓库;
- 就是按下葫芦浮起瓢,你懂我的意思吧。
方案二
poi-tl
个人认为是比较好用,但是如果后端动态数据过多的情况下,建议还是由前端来做为好,双方都可以轻松。
官方文档
文档很详细,该有的都有,就是封装几个poi-tl相关工具类
依赖导入
xml
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.10.0</version>
</dependency>
工具类
java
/**
* Poi-tl模板引擎官方文档:http://deepoove.com/poi-tl/1.10.x/
* @author: Laity
* @Project: JavaLaity
* @Description: word工具类
*/
@Slf4j
public class WordUtil {
/**
* 根据模板填充内容生成word,并下载
*/
public static void downloadWord(HttpServletResponse response, XWPFTemplate template) {
ServletOutputStream outputStream;
try {
//out = new FileOutputStream(filePath);//输出路径(下载到指定路径)
// 将填充之后的模板写入filePath
outputStream=response.getOutputStream();
//将template写到OutputStream中
template.write(outputStream);
outputStream.flush();
outputStream.close();
template.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 只得到这个对象本身的所有属性名及属性值
* @param target 目标对象
* @return Map集合
* @throws IntrospectionException 反射异常
*/
public static Map<String,Object> getOnlySelfFieldNameAndValue(Object target) throws IntrospectionException {
Map<String,Object> map=new HashMap<>();
Class<?> clazz = target.getClass();
Field[] tableFields = clazz.getDeclaredFields();
getAllFieldNameAndValue(target,map,tableFields,clazz);
return map;
}
/**
* 递归获取某个类及其所有父类的所有字段
*/
private static Field[] getSuperClassFields(Field[] tableFields, Class<?> clazz) {
Class<?> superClazz = clazz.getSuperclass();
if (superClazz.equals(Object.class)) {
return tableFields;
}
Field[] tableSuperFields = superClazz.getDeclaredFields();
Field[] c = new Field[tableFields.length + tableSuperFields.length];
System.arraycopy(tableFields, 0, c, 0, tableFields.length);
System.arraycopy(tableSuperFields, 0, c, tableFields.length, tableSuperFields.length);
getSuperClassFields(c, superClazz);
return c;
}
}
Controller层
java
/**
* https://deepoove.com/poi-tl/1.10.x/#hack-loop-table
* @author: Laity
* @Project: JavaLaity
* @Description: word导出接口层
*/
@RestController
@RequestMapping("/word")
@Slf4j
public class WordController {
@Value("${file.readPath}")
private String basePath;
@GetMapping("/test")
public void jiangDu(HttpServletResponse response){
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;fileName=test.docx");
/* word模板地址*/
String resource=basePath+"test.docx";
Map<String, Object> map=new HashMap<>();
// 放测试数据 - 也可以嵌套map,也可以放对象,根据自己的数据进行数据处理
map.put("title", "测试");
// 读取模板templatePath并将paramMap的内容填充进模板,即编辑模板(compile)+渲染数据(render)
/*-------------------策略渲染---------------------*/
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); // 这个有很多方式,有需要直接看文档
// Configure config = Configure.builder().bind("你设置的标签名", 你的渲染策略:policy).build();
XWPFTemplate template = XWPFTemplate.compile(resource, config).render(map);
//这里进行导出
WordUtil.downloadWord(response,template);
}
}
文章中的逻辑代码较为简单,建议去看官方文档来进行使用
问题
- 资源消耗相比较之下较大些
前端Vue操作Word(easy)
- jszip
- jszip是一个用于创建、读取和编辑.zip文件的JavaScript库,且API的使用也很简单。
- jszip-utils
- jszip-utils是与jszip一起使用的跨浏览器的工具库
-
使用getBinaryContent():读取并获得模板文件的二进制内容
- docxtemplater
- docxtemplater是一种邮件合并工具,它以编程方式使用,处理条件、循环,并且可以扩展为表格、HTML、图像等。
- FileSaver
- FileSaver.js 是在客户端保存文件的解决方案,非常适合需要生成文件,或者保存不应该发送到外部服务器的敏感信息的应用。
-
使用saveAs(blob, "test.docx"):将目标文件对象保存为目标类型的文件,并命名
人生如一场修行。得意时,一日看尽长安花;艰难时,潦倒新停浊酒杯。但生命的跋涉不能回头,哪怕畏途巉岩不可攀,也要会当凌绝顶;哪怕无人会登临意,也要猛志固常在。我是Laity,正在前行的Laity。