springboot导出word文档

springboot导出word文档

    • 使用方案 poi-tl
    • 使用方式
      • maven依赖
      • 文件模板
      • 导出代码
    • 可能遇到的问题
      • java.lang.NoClassDefFoundError:org/apache/xmlbeans/impl/schema/DocumentFactory
      • java.lang.NoSuchMethodError:org.apache.logging.log4j.Logger.atDebug()Lorg/apache/logging/log4j/LogBuilder;
      • java.lang.NoClassDefFoundError:org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream
      • 其他问题

使用方案 poi-tl

本带打算使用Freemarker,但是freemarker导出docx格式文档会出现office无法打开等问题,并且模板制作过程比较复杂,基于XML的ftl模板后期维护也比较繁琐,而poi-tl在这一点上可以解决以上问题
pol-ti中文文档
springboot导出word文档_第1张图片

使用方式

maven依赖

本人springbot版本2.1.8.RELEASE,版本属实有点低,所以出现的问题肯定也不少了哈哈。。
最新版本查看

		<dependency>
			<groupId>com.deepoove</groupId>
			<artifactId>poi-tl</artifactId>
			<version>1.12.1</version>
		</dependency>

文件模板

springboot导出word文档_第2张图片
如果图片样式固定的话要这样处理,在官方文档中的 参考这里
鼠标右键图片----》查看可选文字—》然后跟下图一样填写就行
springboot导出word文档_第3张图片
需要注意的是如果该字段对应的图片为null,例如:

json.put("szhzxImg", null);

则导出的word文档图片会显示原来模板里的图片,目前也没看出来官方文档说怎么处理所以我个人就直接放了一张透明底色图片上去,效果如下:
springboot导出word文档_第4张图片

导出代码


 @Autowired
 ResourceLoader resourceLoader;

 public void produceWord(String ftlName, String outPutName, JSONObject json, HttpServletResponse response, HttpServletRequest request) {
        try {
            response.reset();
            String userAgent = request.getHeader("User-Agent");
            if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
                outPutName = URLEncoder.encode(outPutName, "UTF-8");
            } else {
                // 非IE浏览器的处理:
                outPutName = new String(outPutName.getBytes("UTF-8"), "ISO8859-1");
            }
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;fileName=" + outPutName);
            json.put("zrbmImg", Pictures.ofLocal("D:/home/ftl/139631707.png").create());
            //默认图片default.png
            json.put("szhzxImg", Pictures.ofLocal("D:/home/ftl/default.png");

             //模板路径
            InputStream inputStream = resourceLoader.getResource("classpath:template/信息系统备案表.docx").getInputStream();
            XWPFTemplate template = XWPFTemplate.compile(inputStream).render(json);
            OutputStream out = response.getOutputStream();
            BufferedOutputStream bos = new BufferedOutputStream(out);
            template.write(bos);
            bos.flush();
            out.flush();
            PoitlIOUtils.closeQuietlyMulti(template, bos, out);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

可能遇到的问题

因为poi-tl 1.12.1是基于poi5.2+版本的,本身已经有了poi相关的依赖所以无需再单独引入
,当然也可能会有其他的依赖冲突
springboot导出word文档_第5张图片

java.lang.NoClassDefFoundError:org/apache/xmlbeans/impl/schema/DocumentFactory

引入依赖:

		<dependency>
			<groupId>org.apache.xmlbeans</groupId>
			<artifactId>xmlbeans</artifactId>
			<version>5.0.2</version>
		</dependency>

java.lang.NoSuchMethodError:org.apache.logging.log4j.Logger.atDebug()Lorg/apache/logging/log4j/LogBuilder;

原因:SpringBoot 依赖的 log4j 版本过低。
解决方案:设置log4j2版本

    <properties>
        <java.version>1.8</java.version>
        <log4j2.version>2.17.2</log4j2.version>
    </properties>

java.lang.NoClassDefFoundError:org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream

解决方案:

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>

其他问题

别往下翻了没有了就记得上面几个了嘿嘿

你可能感兴趣的:(word,spring,boot,java)