Thymeleaf實現自定義模板導出pdf或word


技術棧:springboot+thymeleaf+pdf引擎

1.導入對應的jar包,使用srpingboot快速實現

       <!--引入thymeleaf相關的依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
 <!--用於pdf的頁面渲染自帶webkit瀏覽器內核-->
        <dependency>
            <groupId>com.openhtmltopdf</groupId>
            <artifactId>openhtmltopdf-core</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.openhtmltopdf</groupId>
            <artifactId>openhtmltopdf-pdfbox</artifactId>
            <version>1.0.0</version>
        </dependency>

2.生成模板的java代碼實現,文件路徑需要修改您對應的位置

 /**
     * 本地
     *構建一個pdf
     * @param templateName 模板名稱
     * @param variables    模板變量
     * @throws Exception
     */
    public static void buildResource( String templateName, Map<String, Object> variables) throws Exception {
        //thymeleaf構造模板引擎;給html文件賦值
        ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
        //默認是找classpath路徑下的資源
        resolver.setPrefix("testPDF/templates/");
        resolver.setSuffix(".html");//模板文件后綴
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(resolver);
        //構造上下文
        Context context = new Context();
        context.setVariable("templateName",templateName);
        //設置變量
        context.setVariables(variables);
        //TODO 渲染模板,返回的生成的模板的字符串
        String example = templateEngine.process("parent", context);
        // 生成pdf文件地址
        String pdfPath ="D://"+ new Random().nextInt(30) + "-" + System.nanoTime() + ".pdf";
        File file = new File(pdfPath);
        file.createNewFile();
        FileOutputStream os = new FileOutputStream(file);
        //構建pdf的預覽
        PdfRendererBuilder builder = new PdfRendererBuilder();
        //設置字體支持中文
        builder.useFont(new ClassPathResource("testPDF/fonts/simsun.ttf").getFile(), "simsun");
        //使用快速渲染器
        builder.useFastMode();

        //String s = ResourceUtils.getURL("testPDF/templates/").toString(); 獲取資源路徑
        String path = new ClassPathResource("/testPDF/templates").getPath();//獲取項目下的資源路徑
        //withHtmlContent()參數一是模板,參數二模板的基礎路徑
        builder.withHtmlContent(example,new ClassPathResource("/testPDF/templates").getPath());
        //輸出pdf的結果
        builder.toStream(os);
        builder.run();
        //設置字符編碼
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(os));
        writer.flush();
        writer.close();
    }

    /**
     * TODO 通過接口接口請求生成pdf模板;有pdf預覽窗口
     * @param templateName
     * @param variables
     * @throws Exception
     */
    public static void requestBuildResource(HttpServletResponse response, String templateName, Map<String, Object> variables) throws Exception {
        //thymeleaf構造模板引擎;給html文件賦值
        ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
        //默認是找classpath路徑下的資源
        resolver.setPrefix("testPDF/templates/");
        resolver.setSuffix(".html");//模板文件后綴
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(resolver);
        //構造上下文(Model)
        Context context = new Context();
        //設置變量
        context.setVariables(variables);
        //TODO 渲染模板,返回的生成的模板的字符串
        String example = templateEngine.process(templateName, context);

        //TODO 生成pdf,瀏覽器進行展示
        response.setHeader("Content-Disposition", "filename=" + new String(("pdfFileName" + ".pdf").getBytes(), "iso8859-1"));
        //生成pdf,瀏覽器不進行展示,默認附件下載;原因:attachment標記以附件方式下載保存
        // response.setHeader("Content-Disposition", "attachment;fileName=" + new String(("templateName" + ".pdf").getBytes("gb2312"), "ISO8859-1"));
        OutputStream os = response.getOutputStream();
        //構建pdf的構造器
        PdfRendererBuilder builder = new PdfRendererBuilder();
        //設置字體支持中文
        //
        builder.useFont(new ClassPathResource("testPDF/fonts/simsun.ttf").getFile(), "simsun");
        builder.useFastMode();
        //withHtmlContent()參數:提供一個包含要轉換為PDF的XHTML/XML的字符串
        //ResourceUtils.getURL()獲取資源的地址
        builder.withHtmlContent(example, ResourceUtils.getURL("testPDF/templates/").toString());
        //輸出pdf的結果
        builder.toStream(os);
        builder.run();
        //設置字符編碼
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(os));
        writer.flush();
        writer.close();
    }


    /**
     * 生成本地word
     * @param variables 模板需要的數據
     * @throws Exception
     */
    public static void buildWord( Map<String, Object> variables) throws Exception {

        ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
        //默認是找classpath路徑下的資源
        resolver.setPrefix("testPDF/templates/");
        resolver.setSuffix(".html");//模板文件后綴
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(resolver);
        //構造上下文
        Context context = new Context();

        context.setVariables(variables);
        // 生成word文件地址
        String pdfPath ="D://"+ new Random().nextInt(30) + "-" + System.nanoTime() + ".docx";
        File file = new File(pdfPath);
        file.createNewFile();
        FileOutputStream os = new FileOutputStream(file);

        try( PrintWriter writer = new PrintWriter(new OutputStreamWriter(os))) {
            //TODO 參數一是模板;參數二:上下文數據模板需要讀取的數據容器;參數三writer輸出流是指定輸出到那個地方
            templateEngine.process("one",context, writer);
        }catch (Exception e){
            log.error("導出word文件出錯啦:{}", e.getMessage());
        }
    }

    /**
     * 通過接口生成word
     * @param response
     * @param variables
     * @throws Exception
     */
    public static void requestbuildWord(HttpServletResponse response, Map<String, Object> variables) throws Exception {

        ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
        //默認是找classpath路徑下的資源
        resolver.setPrefix("testPDF/templates/");
        resolver.setSuffix(".html");//模板文件后綴
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(resolver);
        //構造上下文
        Context context = new Context();
        context.setVariable("templateName", "one");
        context.setVariables(variables);
        // 生成word文件地址
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/msword");
        response.setHeader("Content-Disposition", "attachment;fileName=" + new String(("test" + ".xls").getBytes("gb2312"), "ISO8859-1"));
        try( PrintWriter writer = new PrintWriter(new OutputStreamWriter(response.getOutputStream()))) {
            //TODO 參數一是模板;參數二:上下文數據模板需要讀取的數據容器;參數三writer輸出流是指定輸出到那個地方
            templateEngine.process("parent",context, writer);
        }catch (Exception e){
            log.error("導出word文件出錯啦:{}", e.getMessage());
        }
    }

3.thymeleaf模板代碼,自定義模板需要了解thymeleaf語法,可自行搜索thymeleaf官網學習

注意導出pdf一定要用這個parent父頁面,先引入執行,原因父頁面設置的中文編碼的使用,防止導出中文亂碼

parent頁面代碼

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
    <meta charset="UTF-8"/>
    <title >父頁面</title>
    <style>
        @page {
            size: A4;
            @top-center {
                content: element(header);
            }
            @bottom-center {
                content: '自由行產品詳情';
                font-family: 'simsun', serif;
            }
        }

        html, body {
            font-family: 'simsun', serif;
        }

        table {
            -fs-table-paginate: paginate;
            border-collapse: collapse;
        }

        table, td, th {
            border: 1px solid #555;
            padding: 3px 5px;
        }

        th {
            background-color: #eff3fa;
        }

        #page-header {
            position: running(header);
            border-bottom: 1px solid #555;
            padding: 5px;
        }

        #page-header-text {
            font-size: 16px;
        }

        #page-header-num:after {
            float: right;
            text-align: right;
            content: counter(page) '/' counter(pages);
        }
    </style>
</head>
<body>
<div id="page-header">
    <span id="page-header-text">kindleboy</span>
    <span id="page-header-num"></span>
</div>
<div th:include="${templateName}::body"></div>
</body>
</html>
parent頁面

測試模板頁面代碼,自行編輯

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
<div>
    <p>測試導出pdf</p>
    <p th:text="'weclcome to guangzhou,'+${user.username}">靜態數據</p>
</div>
</body>
</html>

字體中文設置文件:simsun.ttf

下面鏈接獲取設置simsun.tff文件鏈接

鏈接:https://pan.baidu.com/s/1FkGDX9VcM4XNAlLuvvDQmA
提取碼:tdqa

注意功能發布到linux服務器上,讀取字體文件一定要用流的方式讀取simsun.tff文件,防止讀取不了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM