最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

poi

旗下网站admin22浏览0评论

poi

poi

poi-tl根据word模板导出word、使用spring-thymeleaf模板生成html并通过docx4j把html转word,使用jxls根据excel模板导出excel(2)

thymeleaf

官网

/doc/tutorials/3.0/thymeleafspring.html 

参考

/u010739551/article/details/81566987

Thymeleaf是用于Web和独立环境的现代服务器端Java模板引擎。

Thymeleaf的主要目标是将优雅的自然模板带到您的开发工作流程中—HTML能够在浏览器中正确显示,并且可以作为静态原型,从而在开发团队中实现更强大的协作。Thymeleaf能够处理HTML,XML,JavaScript,CSS甚至纯文本。

Thymeleaf的主要目标是提供一个优雅和高度可维护的创建模板的方式。 为了实现这一点,它建立在自然模板的概念之上,以不影响模板作为设计原型的方式将其逻辑注入到模板文件中。 这改善了设计沟通,弥合了前端设计和开发人员之间的理解偏差。

自动生成WORD文档并下载,导出WORD文档 thymeleaf *  配置jxls后thymeleaf不好使 因thymeleaf默认找后缀为.html的模板  而jxls  指定了后缀为 .xls  所以不能使用Mode直接返回视图 需通过spring thymeleaf 把docx4j转word并下载 *  所以thymeleaf找不到相关模板  解决方案为demo2  通过docx4j 使  html 转word 并下载

docx4j

官网

/trac/docx4j 

例子

https://github/plutext/docx4j/tree/master/docx4j-samples-docx4j     

欢迎使用docx4j

docx4j是一个开源(ASLv2)Java库,用于创建和处理Microsoft Open XML(Word docx,Powerpoint pptx和Excel xlsx)文件。

它类似于Microsoft的OpenXML SDK,但适用于Java。docx4j使用JAXB创建内存中的对象表示形式。

它的重点是功能:如果文件格式支持它,则可以使用docx4j来实现。但是首先,您需要花一些时间来了解JAXB和Open XML文件结构

docx4j由Plutext Pty Ltd于2008年创建-将OpenXML4J用于OPC。Plutext仍然推动着该项目的发展,但是从那时起docx4j受益于许多个人的贡献。贡献者列在docx4j的pom.xml中。

docxj4简介

“现在有了docx4j,使用我设想的方法生成Word文档要容易得多。”

“过去一个月我一直在新产品上使用docx4j,我对docx4j的使用量印象深刻并感到感谢。”

“该库为您提供了从Java创建/加载/编辑/编写Word docx文档所需的一切,并附带了Maven仓库,在线Javadoc和不错的示例代码集。您还需要什么呢?:-

thymeleaf

1.导入依赖

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>

    <!--docx4j start-->         <dependency>             <groupId>org.docx4j</groupId>             <artifactId>docx4j-ImportXHTML</artifactId>             <version>8.0.0</version>         </dependency>         <dependency>             <groupId>org.docx4j</groupId>             <artifactId>docx4j-JAXB-ReferenceImpl</artifactId>             <version>8.0.0</version>         </dependency>         <!--docx4j start-->

2.模板

thymeleafDemo1.html模板

<html lang="zh_CN"><head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/> <meta http-equiv="X-UA-Compatible" content="ie=edge"/> <title>Hello report.</title></head><body><h1 data-th-text="${hello}">Hello report.</h1><br/><br/><img src="/2022010622205164259.png" class="header-logo"/><br/><h1>base64Image写死图片base64</h1><img src="" data-th-src="${base64Image}" width="80px" height="60px"/><br/><h1>imagData</h1><img src="" data-th-src="${imagData}" width="80px" height="60px"/><br/><h1>imagData2</h1><img src="" data-th-src="${imagData2}" width="80px" height="60px"/><br/><table> <thead> <tr> <th>id</th> <th>信息</th> <th>日期</th> <th>图片</th> </tr> </thead> <tbody> <tr data-th-each="hel : ${hellos}"> <th data-th-text="${hel.id}">id</th> <th data-th-text="${hel.hello}">message</th> <th data-th-text="${#dates.format(hel.date, 'yyyy-MM-dd HH:mm')}">date</th> <th> <!--<img src="/2022010622205261527.png"--> <!--data-th-src="${base64Image}"--> <!--data-th-title="'title_' + ${hel.hello}" title="title"--> <!--data-th-alt="'title_' + ${hel.hello}" alt="alt"--> <!--width="80px"--> <!--height="60px"/>--> <img src="" data-th-src="${base64Image}" data-th-title="'title_' + ${hel.hello}" title="title" data-th-alt="'title_' + ${hel.hello}" alt="alt" width="80px" height="60px"/> </th> </tr> </tbody></table></body></html>

java

示例:自动生成WORD文档并下载,导出WORD文档 thymeleaf* 配置jxls后thymeleaf不好使 因thymeleaf默认找后缀为.html的模板 而jxls 指定了后缀为 .xls 所以不能使用Mode直接返回视图 需通过docx4j 把html转word并下载* 所以thymeleaf找不到相关模板 解决方案为demo2 通过docx4j 使 html 转word 并下载 package com.shan.mydemo.controller;import com.shan.mydemo.domain.*;import io.swagger.annotations.ApiOperation;import org.apachemons.lang.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.thymeleaf.context.Context;import sun.misc.BASE64Encoder;import javax.servlet.http.HttpServletResponse;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.URL;import java.util.*;import java.util.concurrent.ThreadLocalRandom;import java.util.stream.IntStream;/** * @author shanc * @version 1.0 * jxls 案例 */@Controller@RequestMapping("/thymeleafDemo")public class ThymeleafDemoController { @Autowired private InlineImageWordGenerator docGenerator; /** * 作者: shanc * 时间: 2021/4/19 11:07 * 描述: * 配置jxls后thymeleaf不好使 因thymeleaf默认找后缀为.html的模板 而jxls 指定了后缀为 .xls 所以不能使用Mode直接返回视图 * 需通过docx4j 使 把html转word并下载 */ @GetMapping("/demo1") public String getUserList(Model mode) { String base64Image = "/2022010622205164259.png"; List<HelloFO> list=new ArrayList<>(); ThreadLocalRandom tl=ThreadLocalRandom.current(); IntStream.range(10,tl.nextInt(20,40)).mapToObj( i -> { HelloFO build = HelloFO.builder() .id(String.valueOf(i)) .hello("name-" + i) .date(new Date()).build(); return build; } ).forEach(list::add); URL url = this.getClass().getClassLoader().getResource("static/default-image-placeholder-china-coal_800x600.png"); String path = url.getPath(); System.out.println(path); byte[] data = null; // 读取图片字节数组 try { InputStream in = new FileInputStream(path); data = new byte[in.available()]; in.read(data); in.close(); } catch (IOException e) { e.printStackTrace(); } // 对字节数组Base64编码 BASE64Encoder encoder = new BASE64Encoder(); String imagData = encoder.encode(Objects.requireNonNull(data)); // 返回Base64编码过的字节数组字符串 System.out.println("本地图片转换Base64:" + imagData); //照片转bast64 String imagData2 = ImageUtils.toBase64DataURL(url); //写死图片base64 mode.addAttribute("base64Image", base64Image); //mode.addAttribute("base64Image", imagData2); //通过流转 mode.addAttribute("imagData", "data:image/png;base64,"+imagData); //工具转 mode.addAttribute("imagData2", imagData2); mode.addAttribute("hellos", list); mode.addAttribute("hello","Hello report demo 1."); return "thymeleaf/thymeleafDemo1"; } /** * 示例:自动生成WORD文档并下载,导出WORD文档 thymeleaf * 配置jxls后thymeleaf不好使 因thymeleaf默认找后缀为.html的模板 而jxls 指定了后缀为 .xls 所以不能使用Mode直接返回视图 需通过spring thymeleaf 把html转word并下载 * 所以thymeleaf找不到相关模板 解决方案为demo2 通过docx4j 使 html 转word 并下载 * @param response response * @throws IOException e * */ @ApiOperation("示例:自动生成WORD文档并下载,导出WORD文档") @GetMapping("/demo2") public void demo2(HttpServletResponse response) throws IOException { Context ctx =new Context(); List<HelloFO> list=new ArrayList<>(); ThreadLocalRandom tl=ThreadLocalRandom.current(); IntStream.range(10,tl.nextInt(20,40)).mapToObj( i -> { HelloFO build = HelloFO.builder() .id(String.valueOf(i)) .hello("name-" + i) .date(new Date()) .build(); return build; } ).forEach(list::add); //通过流转 URL url = this.getClass().getClassLoader().getResource("static/default-image-placeholder-china-coal_800x600.png"); String base64Image = ImageUtils.toBase64DataURL(url); ctx.setVariable("base64Image", base64Image); ctx.setVariable("hellos", list); ctx.setVariable("hello","Hello report demo 1."); // set response file name String fileName = "hello-report-2.docx"; HttpServletResponseUtils.setDownloadHeader(fileName, response); // do generate doc file docGenerator.generate("thymeleaf/thymeleafDemo2", ctx, response.getOutputStream()); } @ApiOperation("示例:导出出题表导出") @GetMapping("/reply-question-export") public void replyQuestionExport(HttpServletResponse response) throws IOException { // set variable: hello, as title Context ctx = new Context(); ctx.setVariable("title", "申报高级工程师系列人员论文答辩出题表"); // dclrQuestionList List<Map<String, String>> dclrQuestionList = new LinkedList<>(); ThreadLocalRandom random = ThreadLocalRandom.current(); IntStream.range(10, random.nextInt(10, 33)) .mapToObj(i -> { Map<String, String> dcleQuestion = new LinkedHashMap<>(); dcleQuestion.put("orgName", "单位名称_" + i); dcleQuestion.put("userName", "姓名_" + i); dcleQuestion.put("paperTitleOrSummary", "论文题目内容摘要_" + i); dcleQuestion.put("question1", "问题1_" + i); dcleQuestion.put("question2", "问题2_" + i); dcleQuestion.put("question3", "问题3_" + i); dcleQuestion.put("question4", "问题4_" + i); dcleQuestion.put("expertName", "专家姓名_" + i); return dcleQuestion; }) .forEach(dclrQuestionList::add); ctx.setVariable("dclrQuestionList", dclrQuestionList); // set response file name String fileName = "reply-question-" + System.currentTimeMillis() + ".docx"; HttpServletResponseUtils.setDownloadHeader(fileName, response); // do generate doc file docGenerator.generate("thymeleaf/reply-question", ctx, response.getOutputStream()); } /** * 作者: shanc * 时间: 2021/4/19 10:55 * 描述: jxls根据excel模板导出excel */ @GetMapping("/title-registry-form-excel") public String titleRegistryFormExcel(Model model) { String [] gender={"男","女"}; Date now = new Date(); model.addAttribute("org_name", "中国中煤能源集团有限公司"); model.addAttribute("year_yyyy", "2020"); model.addAttribute("series_name_short", "会计"); model.addAttribute("qualification_name", "高级会计师"); model.addAttribute("proj_level", "高级"); model.addAttribute("fill_form_user_name", "管理员"); model.addAttribute("telephone", "18888888888"); model.addAttribute("fill_form_date", TasDateTimeUtils.format(now, "yyyy年MM月dd日")); List<Map<String,Object>> list =new ArrayList<>(); ThreadLocalRandom random =ThreadLocalRandom.current(); IntStream.range(0,random.nextInt(10,30)).mapToObj(i ->{ Map<String,Object> row=new LinkedHashMap<>(); row.put("sys_no","00000"+i); row.put("org_name", "单位_" + i); row.put("full_name", "姓名_" + i); row.put("gender_desc", gender[random.nextInt(0, 2)]); row.put("birth_date_str", TasDateTimeUtils.format(now, "yyyy-MM-dd")); List<String> strings = Arrays.asList("2020-12-01", "2020-12-02"); String graduation_date_list_str = StringUtils.join(strings,"\n\r" ); System.out.println(graduation_date_list_str); row.put("graduation_date_list_str", graduation_date_list_str); row.put("graduation_school_list_str",StringUtils.join(Arrays.asList("烟台大学","南京大学"),"\n\r") ); return row; } ).forEach(list::add); model.addAttribute("dataList", list); // file name model.addAttribute("JXLS_FILENAME_KEY", "title-registry-form-" + System.currentTimeMillis()); // generate view return "report/title-registry-form-v1"; } /** * 作者: shanc * 时间: 2021/4/19 10:55 * 描述: 自定义模板 jxls根据excel模板导出excel */ @GetMapping("/jxls-demo2") public String jxlsDemo2(Model model) { String [] gender={"男","女"}; Date now = new Date(); model.addAttribute("org_name", "中国中煤能源集团有限公司"); model.addAttribute("fill_form_user_name", "管理员"); List<Map<String,Object>> list =new ArrayList<>(); ThreadLocalRandom random =ThreadLocalRandom.current(); IntStream.range(0,random.nextInt(10,30)).mapToObj(i ->{ Map<String,Object> row=new LinkedHashMap<>(); row.put("sys_no","00000"+i); row.put("org_name", "单位_" + i); row.put("full_name", "姓名_" + i); row.put("gender_desc", gender[random.nextInt(0, 2)]); row.put("birth_date_str", TasDateTimeUtils.format(now, "yyyy-MM-dd")); System.out.println(row); return row; } ).forEach(list::add); model.addAttribute("dataList", list); // file name model.addAttribute("JXLS_FILENAME_KEY", "jxls-demo2-" + System.currentTimeMillis()); // generate view return "report/jxls-list3"; }}

测试

 

通过docx4j 使html模板转word并导出

增加依赖

<dependency>     <groupId>org.docx4j</groupId>     <artifactId>docx4j-ImportXHTML</artifactId>     <version>8.0.0</version> </dependency> <dependency>     <groupId>org.docx4j</groupId>     <artifactId>docx4j-JAXB-ReferenceImpl</artifactId>     <version>8.0.0</version> </dependency>

工具类

package com.shan.service.impl;import lombok.extern.slf4j.Slf4j;import org.apachemons.io.output.StringBuilderWriter;import org.docx4j.convert.in.xhtml.XHTMLImporterImpl;import org.docx4j.openpackaging.exceptions.Docx4JException;import org.docx4j.openpackaging.packages.WordprocessingMLPackage;import org.springframework.stereotype.Component;import org.thymeleaf.context.IContext;import org.thymeleaf.spring5.SpringTemplateEngine;import javax.annotation.Resource;import java.io.IOException;import java.io.OutputStream;/** * Word doc generator. * * @author zhangbr * @date 2020-12-31 */@Component@Slf4jpublic class InlineImageWordGenerator { @Resource private SpringTemplateEngine templateEngine; /** * generate doc and write to OutputStream * * @param templateName templateName * @param ctx ctx, to set variables * @param os OutputStream, e.g. {@code HttpServletResponse.getOutputStream()} * @throws */ public void generate(String templateName, IContext ctx, OutputStream os) { try (OutputStream os2 = os) { // generate html string StringBuilderWriter sbw2 = new StringBuilderWriter(); templateEngine.process(templateName, ctx, sbw2); String htmlString = sbw2.toString(); if (log.isDebugEnabled()) { log.debug("Template generated html:{}{}{}", System.lineSeparator(), htmlString, System.lineSeparator()); } // convert (x)html string to word doc WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage(); XHTMLImporterImpl xhtmlImporter = new XHTMLImporterImpl(wordMLPackage); xhtmlImporter.setHyperlinkStyle("Hyperlink"); wordMLPackage.getMainDocumentPart().getContent() .addAll(xhtmlImporter.convert(htmlString, null)); // write to output stream wordMLPackage.save(os2); } catch (Docx4JException | IOException e) { throw new RuntimeException("error"); } }}

模板

thymeleafDemo2.html 模板

<html lang="zh_CN"><head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/> <meta http-equiv="X-UA-Compatible" content="ie=edge"/> <title>Hello report.</title></head><body><h1 data-th-text="${hello}">Hello report.</h1><br/><table> <thead> <tr> <th>id</th> <th>信息</th> <th>日期</th> <th>图片</th> </tr> </thead> <tbody> <tr data-th-each="hel : ${hellos}"> <th data-th-text="${hel.id}">id</th> <th data-th-text="${hel.hello}">message</th> <th data-th-text="${#dates.format(hel.date, 'yyyy-MM-dd HH:mm')}">date</th> <th> <img src="" data-th-src="${base64Image}" data-th-title="'title_' + ${hel.hello}" title="title" data-th-alt="'title_' + ${hel.hello}" alt="alt" width="80px" height="60px"/> </th> </tr> </tbody></table></body></html>

测试

localhost:9001/thymeleafDemo/demo2

 

打开下载文件

 

 

 

reply-question.html模板

<html lang="zh_CN"><head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/> <meta http-equiv="X-UA-Compatible" content="ie=edge"/> <title data-th-text="${title}">论文答辩出题表</title></head><body data-th-each="dclrQuestion : ${dclrQuestionList}"><div> <p style="text-align:center;" ><span style="font-size:18pt; font-weight:bold"></span ></p> <p style="text-align:center;" data-th-text="${title}">申报高级工程师系列人员论文答辩出题表</p> <p style="text-align:center;" ><span style="font-size:18pt">&#xa0;</span ></p> <div> <table border="1px" cellspacing="0" cellpadding="0" style="border-collapse:collapse; width:524.1pt"> <tr> <td>单位</td> <td colspan="3" data-th-text="${dclrQuestionName}">建安总部机关</td> <td style="padding:0.62pt; vertical-align:middle; width:50.3pt">姓名</td> <td colspan="2" data-th-text="${dclrQuestion.userName}">张三</td> </tr> <tr> <td><p ><span>&#xa0;</span></p>论文<br/>题目<br/>内容<br/>摘要<p ><span>&#xa0;</span></p> </td> <td colspan="6" data-th-text="${dclrQuestion.paperTitleOrSummary}">选煤厂胶带输送机安装技术要点探讨</td> </tr> <tr> <td rowspan="4">答<br/>辩<br/>题<br/>目</td> <td>1</td> <td colspan="5" data-th-text="${dclrQuestion.question1}">带式输送机胶带接头硫化工艺要点。</td> </tr> <tr> <td>2</td> <td colspan="5" data-th-text="${dclrQuestion.question2}">带式输送机在机体中跑偏,分析原因给出解决方案?</td> </tr> <tr> <td>3</td> <td colspan="5" data-th-text="${dclrQuestion.question3}">带式输送机驱动装置安装时二次灌浆工序如何进行?</td> </tr> <tr> <td>4</td> <td colspan="5" data-th-text="${dclrQuestion.question4}">机驱动装置安装时二</td> </tr> <tr style="border: none; height: 0px; "> <td style="width: 85pt"></td> <td style="width: 85pt"></td> <td style="width: 85pt"></td> <td style="width: 85pt"></td> <td style="width: 85pt"></td> <td style="width: 85pt"></td> </tr> </table> </div> <p> <span>&#xa0;</span> </p> <p ><span style="font-family: 宋体; font-size: 14pt" >出题专家:</span><span style="font-family: 宋体; font-size: 14pt" data-th-text="${dclrQuestion.expertName}" >范强</span> </p></div></body></html>

测试

localhost:9001/thymeleafDemo/reply-question-export

打开下载文件

使用jxls根据excel模板生成excel

看下篇文章

 

poi-tl根据word模板导出word、使用spring-thymeleaf模板生成html并通过docx4j把html转word,使用jxls根据excel

发布评论

评论列表(0)

  1. 暂无评论