最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot使用freemarker導出word文件方法詳解

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

1、前言

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

2、需求說明

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

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

  • username:員工姓名
  • idno:身份證號碼
  • hireDate:入職日期
  • work:職位
  • endDate:離職日期

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

3、編碼

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

我會在此主干基礎上開發(fā)

3.1、導入依賴

<!--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");//身份證號
    map.put("hireDate", "2021年12月12日");//入職日期
    map.put("work", "Java軟件工程師");//職務
    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 判斷字符串是否有長度
     */
    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導出,工具類
 */
public class FreemarkerExportWordUtil {
    private static Configuration configuration = null;
    static {
        configuration = new Configuration(new Version("2.3.0"));
        configuration.setDefaultEncoding("utf-8");
        //獲取模板路徑    setClassForTemplateLoading 這個方法默認路徑是webRoot 路徑下
        configuration.setClassForTemplateLoading(FreemarkerExportWordUtil.class, "/templates");
    }
    private FreemarkerExportWordUtil() {
        throw new AssertionError();
    }
    /**
     * 根據(jù) /resources/templates 目錄下的ftl模板文件生成文件并寫到客戶端進行下載
     * @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) {
        //臨時文件
        String name = "template.doc";
        File f = new File(name);
        Template t = template;
        try {
            // 這個地方不能使用FileWriter因為需要指定編碼類型否則生成的Word文檔會因為有無法識別的編碼而無法打開
            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 響應對象
     * @param realFileName 真實文件名
     * @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);
    }
    /**
     * 百分號編碼工具方法
     *
     * @param s 需要百分號編碼的字符串
     * @return 百分號編碼后的字符串
     */
    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模板文件呢?很簡單,跟著下面步驟做即可

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

2、將該word文檔導出成demo.xml文檔,如下:

然后:

這樣桌面就會多一個demo.xml文件,此時關閉demo.doc文件,打開demo.xml文件進行編輯

3、修改Demo.xml文件

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

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

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

3.5、測試

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

OK,到此測試成功了

4、word轉pdf

有些場景需要導出pdf,那么就需要將生成的臨時word文件轉成pdf后再導出了,下面就介紹一下word轉成pdf的方法吧

首先需要導入依賴:

<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文檔轉成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文檔轉成PDF文檔時,發(fā)生異常:{}", e.getLocalizedMessage());
    } finally {
        //關閉資源
        try {
            if(docxInputStream != null){
                docxInputStream.close();
            }
            if(outputStream != null){
                outputStream.close();
            }
            if(converter != null){
                converter.shutDown();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

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

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

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

5、總結

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

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

相關文章

  • Java?Servlet異步請求開啟的簡單步驟

    Java?Servlet異步請求開啟的簡單步驟

    Java servlet是大家公認的服務器端web技術的標準,包括jsp,jsf,和大量的web框架,soap,RESTful web service api,還有新聞供應,下面這篇文章主要給大家介紹了關于Java?Servlet異步請求開啟的簡單步驟,需要的朋友可以參考下
    2022-02-02
  • SpringBoot整合ip2region獲取客戶端IP地理位置信息

    SpringBoot整合ip2region獲取客戶端IP地理位置信息

    在我們?nèi)粘EB開發(fā)工作中,經(jīng)常會有需要獲取客戶端地理位置的需求,本文主要介紹了SpringBoot整合ip2region獲取客戶端IP地理位置信息,具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • Java中BigDecimal比較大小的3種方法(??compareTo()、??equals()??和??compareTo()??)

    Java中BigDecimal比較大小的3種方法(??compareTo()、??equals()??和??compar

    這篇文章主要給大家介紹了關于Java中BigDecimal比較大小的3種方法,方法分別是??compareTo()、??equals()??和??compareTo()??,在Java中使用BigDecimal類來進行精確的數(shù)值計算,需要的朋友可以參考下
    2023-11-11
  • Nacos框架與原理之Nacos的參數(shù)

    Nacos框架與原理之Nacos的參數(shù)

    這篇文章主要介紹了Nacos框架與原理之Nacos的參數(shù),Nacos?中的參數(shù)有很多,如:命名空間、分組名、服務名、保護閾值、服務路由類型、臨時實例等,但下面文章我們要講解的是參數(shù),參數(shù)是什么呢,下面一起進去文章學習詳細內(nèi)容吧
    2022-05-05
  • java獲取圖片的大小、寬度、高度方式

    java獲取圖片的大小、寬度、高度方式

    文章介紹了如何將File對象轉換為MultipartFile對象的過程,并分享了個人經(jīng)驗,希望能為讀者提供參考
    2025-02-02
  • IDEA:Error running,Command line is too long.解決方案

    IDEA:Error running,Command line is too&n

    這篇文章主要介紹了IDEA:Error running,Command line is too long.解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • java.lang.Void類源碼解析

    java.lang.Void類源碼解析

    這篇文章主要介紹了java.lang.Void類源碼解析的相關內(nèi)容,對源碼中的部分內(nèi)容進行解釋,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • MyBatis中模糊查詢使用CONCAT('%',#{str},'%')出錯的解決

    MyBatis中模糊查詢使用CONCAT('%',#{str},'%')出錯的解

    這篇文章主要介紹了MyBatis中模糊查詢使用CONCAT('%',#{str},'%')出錯的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java使用Sftp和Ftp實現(xiàn)對文件的上傳和下載

    Java使用Sftp和Ftp實現(xiàn)對文件的上傳和下載

    這篇文章主要介紹了Java使用Sftp和Ftp實現(xiàn)對文件的上傳和下載,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • SpringMVC路徑匹配中使用通配符問題

    SpringMVC路徑匹配中使用通配符問題

    這篇文章主要介紹了SpringMVC路徑匹配中使用通配符問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論

马龙县| 广西| 上蔡县| 宁武县| 广安市| 嘉禾县| 桃园县| 清流县| 青海省| 邛崃市| 安义县| 永清县| 尼勒克县| 奈曼旗| 乌什县| 汽车| 广饶县| 通州区| 新丰县| 扶沟县| 托里县| 鹤庆县| 万安县| 楚雄市| 东宁县| 从江县| 手游| 永丰县| 甘谷县| 武宣县| 双桥区| 甘孜| 南陵县| 湘阴县| 平罗县| 黑山县| 吉安市| 汉源县| 六盘水市| 哈巴河县| 溧水县|