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

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

thymeleaf

官网

https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html 

参考

https://blog.csdn.net/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

官网

https://www.docx4java.org/trac/docx4j 

例子

https://github.com/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.导入依赖


   org.springframework.boot
   spring-boot-starter-thymeleaf

    
        
            org.docx4j
            docx4j-ImportXHTML
            8.0.0
        

        
            org.docx4j
            docx4j-JAXB-ReferenceImpl
            8.0.0
        

        

2.模板

thymeleafDemo1.html模板



    
    
    
    Hello report.


Hello report.




base64Image写死图片base64


imagData


imagData2


id 信息 日期 图片
id message date alt

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.apache.commons.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.net.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 = "https://img-blog.csdnimg.cn/2022010622205164259.png";
        List 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 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> dclrQuestionList = new LinkedList<>();
        ThreadLocalRandom random = ThreadLocalRandom.current();
        IntStream.range(10, random.nextInt(10, 33))
                .mapToObj(i -> {
                    Map 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> list =new ArrayList<>();
        ThreadLocalRandom random =ThreadLocalRandom.current();
        IntStream.range(0,random.nextInt(10,30)).mapToObj(i ->{
            Map 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 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> list =new ArrayList<>();
        ThreadLocalRandom random =ThreadLocalRandom.current();
        IntStream.range(0,random.nextInt(10,30)).mapToObj(i ->{
                    Map 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";
    }


}

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

测试

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

 

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

增加依赖


    org.docx4j
    docx4j-ImportXHTML
    8.0.0


    org.docx4j
    docx4j-JAXB-ReferenceImpl
    8.0.0

工具类

package com.shan.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.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
@Slf4j
public 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 模板



    
    
    
    Hello report.


Hello report.


id 信息 日期 图片
id message date alt

测试

localhost:9001/thymeleafDemo/demo2

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

 

打开下载文件

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

 

 

 

reply-question.html模板



    
    
    
    论文答辩出题表



申报高级工程师系列人员论文答辩出题表

 

单位 建安总部机关 姓名 张三

 

论文
题目
内容
摘要

 

选煤厂胶带输送机安装技术要点探讨



1 带式输送机胶带接头硫化工艺要点。
2 带式输送机在机体中跑偏,分析原因给出解决方案?
3 带式输送机驱动装置安装时二次灌浆工序如何进行?
4 机驱动装置安装时二

 

出题专家:范强

测试

localhost:9001/thymeleafDemo/reply-question-export

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

打开下载文件

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

使用jxls根据excel模板生成excel

看下篇文章

 

你可能感兴趣的:(SpringBoot,java)