欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot使用freemarker導(dǎo)出word文件方法詳解

 更新時(shí)間:2022年11月21日 14:43:54   作者:小學(xué)生波波  
這篇文章主要介紹了SpringBoot使用freemarker導(dǎo)出word文件方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧

1、前言

在項(xiàng)目中我們有時(shí)間需要根據(jù)一個(gè)word模板文檔,批量生成其他的word文檔,里面的有些值改變一下而已,那怎么做呢?

2、需求說明

假如說,現(xiàn)在我有個(gè)模板文檔,內(nèi)容如下:

現(xiàn)在上面文檔里面有如下變量:

  • username:?jiǎn)T工姓名
  • idno:身份證號(hào)碼
  • hireDate:入職日期
  • work:職位
  • endDate:離職日期

現(xiàn)在我需要針對(duì)不同的員工一鍵生成一份離職證明出來,公司章是一張圖片,也需要生成進(jìn)去,下面我們開始測(cè)試

3、編碼

基礎(chǔ)框架代碼地址:https://gitee.com/colinWu_java/spring-boot-base.git

我會(huì)在此主干基礎(chǔ)上開發(fā)

3.1、導(dǎo)入依賴

<!--freemarker-->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.30</version>
</dependency>

3.2、接口編寫

TestController新增下面接口:

/**
     * 根據(jù)ftl模板模板下載word文檔
     */
@GetMapping("/downloadWord")
public void downloadWord(HttpServletResponse response){
    Map<String, Object> map = new HashMap<>();
    map.put("username", "王天霸");//姓名
    map.put("idno", "429004199601521245");//身份證號(hào)
    map.put("hireDate", "2021年12月12日");//入職日期
    map.put("work", "Java軟件工程師");//職務(wù)
    map.put("endDate", "2022年11月25日");//離職日期
    map.put("imageData", Tools.getBase64ByPath("D:\\demo\\test.png"));//蓋章Base64數(shù)據(jù)(不包含頭信息)
    try {
        FreemarkerExportWordUtil.exportWord(response, map, "離職證明.doc", "EmploymentSeparationCertificate.ftl");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

D:\demo\test.png這張圖片就是下面這張圖片:

3.3、工具類

Tools工具類:

package org.wujiangbo.utils;
import org.wujiangbo.domain.user.User;
import sun.misc.BASE64Encoder;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
 * <p>工具類</p>
 */
public class Tools {
    /**
     * 獲得指定圖片文件的base64編碼數(shù)據(jù)
     * @param filePath 文件路徑
     * @return base64編碼數(shù)據(jù)
     */
    public static String getBase64ByPath(String filePath) {
        if(!hasLength(filePath)){
            return "";
        }
        File file = new File(filePath);
        if(!file.exists()) {
            return "";
        }
        InputStream in = null;
        byte[] data = null;
        try {
            in = new FileInputStream(file);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
        try {
            assert in != null;
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }
    /**
     * @desc 判斷字符串是否有長(zhǎng)度
     */
    public static boolean hasLength(String str) {
        return org.springframework.util.StringUtils.hasLength(str);
    }
}

FreemarkerExportWordUtil工具類:

package org.wujiangbo.utils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
/**
 * 模板word導(dǎo)出,工具類
 */
public class FreemarkerExportWordUtil {
    private static Configuration configuration = null;
    static {
        configuration = new Configuration(new Version("2.3.0"));
        configuration.setDefaultEncoding("utf-8");
        //獲取模板路徑    setClassForTemplateLoading 這個(gè)方法默認(rèn)路徑是webRoot 路徑下
        configuration.setClassForTemplateLoading(FreemarkerExportWordUtil.class, "/templates");
    }
    private FreemarkerExportWordUtil() {
        throw new AssertionError();
    }
    /**
     * 根據(jù) /resources/templates 目錄下的ftl模板文件生成文件并寫到客戶端進(jìn)行下載
     * @param response HttpServletResponse
     * @param map 數(shù)據(jù)集合
     * @param fileName 用戶下載到的文件名稱
     * @param ftlFileName ftl模板文件名稱
     * @throws IOException
     */
    public static void exportWord(HttpServletResponse response, Map map, String fileName, String ftlFileName) throws IOException {
        Template freemarkerTemplate = configuration.getTemplate(ftlFileName);
        // 調(diào)用工具類的createDoc方法生成Word文檔
        File file = createDoc(map, freemarkerTemplate);
        //將word文檔寫到前端
        download(file.getAbsolutePath(), response, fileName);
    }
    private static File createDoc(Map<?, ?> dataMap, Template template) {
        //臨時(shí)文件
        String name = "template.doc";
        File f = new File(name);
        Template t = template;
        try {
            // 這個(gè)地方不能使用FileWriter因?yàn)樾枰付ň幋a類型否則生成的Word文檔會(huì)因?yàn)橛袩o法識(shí)別的編碼而無法打開
            Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        return f;
    }
    //下載文件的公共方法
    public static void download(String filePath, HttpServletResponse response, String fileName) {
        try {
            setAttachmentResponseHeader(response, fileName);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try(
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
                // 輸出流
                BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
        ){
            byte[] buff = new byte[1024];
            int len = 0;
            while ((len = bis.read(buff)) > 0) {
                bos.write(buff, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 下載文件名重新編碼
     * @param response 響應(yīng)對(duì)象
     * @param realFileName 真實(shí)文件名
     * @return
     */
    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
    {
        String percentEncodedFileName = percentEncode(realFileName);
        StringBuilder contentDispositionValue = new StringBuilder();
        contentDispositionValue.append("attachment; filename=")
                .append(percentEncodedFileName)
                .append(";")
                .append("filename*=")
                .append("utf-8''")
                .append(percentEncodedFileName);
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
        response.setHeader("Content-disposition", contentDispositionValue.toString());
        response.setHeader("download-filename", percentEncodedFileName);
    }
    /**
     * 百分號(hào)編碼工具方法
     *
     * @param s 需要百分號(hào)編碼的字符串
     * @return 百分號(hào)編碼后的字符串
     */
    public static String percentEncode(String s) throws UnsupportedEncodingException
    {
        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
        return encode.replaceAll("\\+", "%20");
    }
}

3.4、ftl文件

那么如何制作出ftl模板文件呢?很簡(jiǎn)單,跟著下面步驟做即可

1、首先新建一個(gè)demo.doc文檔,然后內(nèi)容像下面這樣寫好:

2、將該word文檔導(dǎo)出成demo.xml文檔,如下:

然后:

這樣桌面就會(huì)多一個(gè)demo.xml文件,此時(shí)關(guān)閉demo.doc文件,打開demo.xml文件進(jìn)行編輯

3、修改Demo.xml文件

在demo.xml文件中找到剛才所有的變量,然后都用 包 裹 一 下 , 如 : u s e r n a m e 改 成 {}包裹一下,如:username改成 包裹一下,如:username改成{username},idno改成${idno},等等,全部改完

最后搜索pkg:binaryData字符串,用這個(gè)包裹著很大一段字符串,那就是文檔中公章圖片的Base64格式數(shù)據(jù),我們將其全部刪除,用${imageData}變量代替即可,待會(huì)從代碼中給這個(gè)變量賦值即可,就可以將真正的公章圖片替換到文檔中了,而且圖片大小格式什么的,都會(huì)和模板文檔中保持一致,所以模板文檔的格式先調(diào)整后之后再另存為xml文件

修改完成之后,將文件的后綴名由xml改成ftl,然后拷貝到項(xiàng)目resources下的templates目錄下,我這里改成:EmploymentSeparationCertificate.ftl了

3.5、測(cè)試

打開瀏覽器,訪問接口:http://localhost:8001/downloadWord,就可以下載一個(gè)word文檔了,打開后內(nèi)容如下:

OK,到此測(cè)試成功了

4、word轉(zhuǎn)pdf

有些場(chǎng)景需要導(dǎo)出pdf,那么就需要將生成的臨時(shí)word文件轉(zhuǎn)成pdf后再導(dǎo)出了,下面就介紹一下word轉(zhuǎn)成pdf的方法吧

首先需要導(dǎo)入依賴:

<dependency>
    <groupId>com.documents4j</groupId>
    <artifactId>documents4j-local</artifactId>
    <version>1.0.3</version>
</dependency>
<dependency>
    <groupId>com.documents4j</groupId>
    <artifactId>documents4j-transformer-msoffice-word</artifactId>
    <version>1.0.3</version>
</dependency>

工具類:

/**
     * word文檔轉(zhuǎn)成PDF文檔
     * @param wordPath word文檔路徑
     * @param pdfPath pdf文檔路徑
     */
public static void word2pdf(String wordPath, String pdfPath){
    File inputWord = new File(wordPath);
    File outputFile = new File(pdfPath);
    InputStream docxInputStream = null;
    OutputStream outputStream = null;
    IConverter converter = null;
    try  {
        docxInputStream = new FileInputStream(inputWord);
        outputStream = new FileOutputStream(outputFile);
        converter = LocalConverter.builder().build();
        converter.convert(docxInputStream).as(DocumentType.DOCX).to(outputStream).as(DocumentType.PDF).execute();
        outputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
        log.error("word文檔轉(zhuǎn)成PDF文檔時(shí),發(fā)生異常:{}", e.getLocalizedMessage());
    } finally {
        //關(guān)閉資源
        try {
            if(docxInputStream != null){
                docxInputStream.close();
            }
            if(outputStream != null){
                outputStream.close();
            }
            if(converter != null){
                converter.shutDown();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

需要注意的是:要使用這個(gè)工具類的話,運(yùn)行這個(gè)代碼的機(jī)器上需要安裝WPS或者office軟件,否則轉(zhuǎn)換過程中會(huì)報(bào)錯(cuò)(這可能是一個(gè)小瑕疵,我正在尋找其他更加優(yōu)雅的轉(zhuǎn)換方案,有更好辦法的小伙伴,歡迎留言)

我們就調(diào)用這個(gè)工具類將剛才生成的word文檔轉(zhuǎn)成pdf,成功之后內(nèi)容如下:

內(nèi)容和word文檔一致,測(cè)試成功

5、總結(jié)

本文主要介紹了根據(jù)word模板如何導(dǎo)出word文件,已經(jīng)將word文檔如何轉(zhuǎn)成pdf文件大家趕緊練習(xí)起來吧

到此這篇關(guān)于SpringBoot使用freemarker導(dǎo)出word文件方法詳解的文章就介紹到這了,更多相關(guān)SpringBoot導(dǎo)出word內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于javaweb+jsp的游泳館會(huì)員管理系統(tǒng)(附源碼)

    基于javaweb+jsp的游泳館會(huì)員管理系統(tǒng)(附源碼)

    這篇文章主要介紹了基于javaweb+jsp的游泳館會(huì)員管理系統(tǒng),開發(fā)工具eclipse/idea/myeclipse/sts等均可配置運(yùn)行,此源代碼社和課程設(shè)計(jì),大作業(yè)及畢業(yè)設(shè)計(jì)項(xiàng)目,需要的朋友可以參考下
    2022-04-04
  • Mybatis結(jié)果集映射一對(duì)多簡(jiǎn)單入門教程

    Mybatis結(jié)果集映射一對(duì)多簡(jiǎn)單入門教程

    本文給大家介紹Mybatis結(jié)果集映射一對(duì)多簡(jiǎn)單入門教程,包括搭建數(shù)據(jù)庫(kù)環(huán)境的過程,idea搭建maven項(xiàng)目的代碼詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-06-06
  • ZooKeeper入門教程二在單機(jī)和集群環(huán)境下的安裝搭建及使用

    ZooKeeper入門教程二在單機(jī)和集群環(huán)境下的安裝搭建及使用

    本文是ZooKeeper入門系列教程,涵蓋ZooKeeper的安裝使及單機(jī)集群環(huán)境搭建,通過實(shí)例和大量圖表,結(jié)合實(shí)戰(zhàn),幫助學(xué)習(xí)者理解和運(yùn)用,有需要的朋友可以借鑒參考下
    2022-01-01
  • Spring集成Struts與Hibernate入門詳解

    Spring集成Struts與Hibernate入門詳解

    這篇文章主要給大家介紹了關(guān)于Spring集成Struts與Hibernate的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。
    2017-03-03
  • Java流形式返回前端的實(shí)現(xiàn)示例

    Java流形式返回前端的實(shí)現(xiàn)示例

    ? Java后端開發(fā)項(xiàng)目時(shí),需要給前端傳一些數(shù)據(jù),本文主要介紹了Java流形式返回前端的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • java操作mongodb基礎(chǔ)(查詢 排序 輸出list)

    java操作mongodb基礎(chǔ)(查詢 排序 輸出list)

    java操作mongodb基礎(chǔ)學(xué)習(xí)查詢,排序,limit,輸出為list實(shí)例,大家參考使用吧
    2013-12-12
  • MyBatis中的配置文件詳解

    MyBatis中的配置文件詳解

    在?MyBatis?中,配置文件分為?全局配置文件(核心配置文件)和映射配置文件,本文給大家介紹MyBatis中的配置文件相關(guān)知識(shí),感興趣的朋友一起看看吧
    2023-10-10
  • Java Restful API的攔截詳解

    Java Restful API的攔截詳解

    這篇文章主要介紹了Java 調(diào)用Restful API接口的攔截,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2021-09-09
  • Java遞歸來實(shí)現(xiàn)漢諾塔游戲,注釋詳細(xì)

    Java遞歸來實(shí)現(xiàn)漢諾塔游戲,注釋詳細(xì)

    這篇文章介紹了Java遞歸來實(shí)現(xiàn)漢諾塔游戲的方法,文中的代碼注釋介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-11-11
  • java通過注解翻譯字典的實(shí)現(xiàn)示例

    java通過注解翻譯字典的實(shí)現(xiàn)示例

    本文主要介紹了java通過注解翻譯字典的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04

最新評(píng)論