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

java如何根據(jù)提供word模板導(dǎo)出word文檔詳解

 更新時(shí)間:2023年09月28日 09:19:50   作者:吳巴格  
在日常的開發(fā)工作中,我們時(shí)常會(huì)遇到導(dǎo)出Word文檔報(bào)表的需求,比如公司的財(cái)務(wù)報(bào)表、醫(yī)院的患者統(tǒng)計(jì)報(bào)表、電商平臺(tái)的銷售報(bào)表等等,這篇文章主要給大家介紹了關(guān)于java如何根據(jù)提供word模板導(dǎo)出word文檔的相關(guān)資料,需要的朋友可以參考下

本文主要講解,利用poi-tl在word中動(dòng)態(tài)生成表格行,進(jìn)行文字、圖片填充。一共提供了兩種方式,1.基于本地文件 2.基于網(wǎng)絡(luò)文件

本文講解思路,1.先看示例,2. 示例對(duì)應(yīng)的代碼展示 3. 基本概念講解(api自行查閱文檔)。

這樣便于快速展示,不符合你的業(yè)務(wù)需求的可以直接劃走

1.效果示例圖

1.1 word模板

注意:這里提前闡述幾個(gè)概念。

  • 基本上所有的變量都由{{}}包裹,交給poi-tl解析(變量命名隨便你,中文,英文都可以)
  • {{工作經(jīng)歷列表}}下方的[序號(hào)]、[公司名]、[工作時(shí)長(zhǎng)]、[salary]、[聯(lián)系]、[崗位],就是使用了 poi-tl的表格行插件,動(dòng)態(tài)渲染表格行的語(yǔ)法,可以簡(jiǎn)單理解為此處表格對(duì)應(yīng)的每一行就是一個(gè)對(duì)象實(shí)體類,而{{工作經(jīng)歷列表}}就是一個(gè)list
  • {{?申明項(xiàng)列表}} {{item}} {{/申明項(xiàng)列表}},此處則是使用了poi-tl的區(qū)塊對(duì)標(biāo)簽。區(qū)塊對(duì)在此處的,我只是用它來(lái)實(shí)現(xiàn)渲染同一個(gè)表格內(nèi)的多行文本渲染,可以理解為<申明項(xiàng)列表>標(biāo)簽對(duì)應(yīng)的就是一個(gè)list,< item >就是一個(gè)list中的一個(gè)個(gè)對(duì)象元素。并且此處會(huì)觸發(fā),換行后序號(hào)累加的word編排編號(hào)樣式。
  • {{@員工簽字圖片}},此處需要注意,word模板中代表圖片的變量,必須要加上@特殊符號(hào)修飾!

1.2 參數(shù)替換后的word

看到這里,如果對(duì)應(yīng)的效果不滿足你的需求,那么你可以出門右轉(zhuǎn)了。

2.代碼展示

maven 依賴,使用poi-tl需要支持 poi高版本

<!--    POI 依賴 使用xlsx xml的格式(即XSSFWorkbook)   -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.17</version>
        </dependency>
        <!--     poi模板導(dǎo)入,主力包      -->
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.12.1</version>
        </dependency>

2.1 根據(jù)網(wǎng)絡(luò)生成word

    /**
     * 根據(jù)網(wǎng)絡(luò)生成word
     **/
    public static void generateByNetWork() {
        String ip = "192.168.x.x";
        // 我這里是用文件服務(wù)器返回的網(wǎng)絡(luò)文件流,你也可以直接放置一個(gè)文件的url
        String pictureUrl = "http://" + ip + ":8080/api/file/download?id=b9e0ac0336a84fc0b4ebb4cdf2c805e0.png";
        HashMap<String, Object> finalMap = new HashMap<>();
        finalMap.put("姓名", "張三");
        finalMap.put("身份證號(hào)", "511232XXXXXXX");
        finalMap.put("手機(jī)號(hào)", "1328292xxxx");
        finalMap.put("員工簽字", "張三");
        finalMap.put("日期", "2023-05-16");
        // 從網(wǎng)絡(luò)流讀取圖片,置入word模板,等待編譯
        if (Validator.isNotEmpty(pictureUrl)) {
            PictureRenderData picture = Pictures.ofUrl(pictureUrl).size(40, 30).create();
            finalMap.put("員工簽字圖片", picture);
        }
        ArrayList<Object> workList = CollUtil.newArrayList();
        finalMap.put("工作經(jīng)歷列表", workList);
        for (int i = 0; i < 3; i++) {
            // 模擬從mysql查詢列表數(shù)據(jù)
            HashMap<String, Object> workItem = new HashMap<>();
            workItem.put("序號(hào)", i + 1);
            workItem.put("公司名", "四川有限公司" + i);
            workItem.put("工作時(shí)長(zhǎng)", i + 10 + "小時(shí)");
            workItem.put("salary", "800" + i);
            workItem.put("聯(lián)系", "項(xiàng)目經(jīng)理" + i);
            workItem.put("崗位", "java工程師" + i);
            workList.add(workItem);
        }
        // 注意:此處用的是 <區(qū)塊對(duì)> key是字符串,value則放置一個(gè)集合,類似于模板引擎的foreach標(biāo)簽
        ArrayList<Object> stateList = CollUtil.newArrayList();
        finalMap.put("申明項(xiàng)列表", stateList);
        // 模擬從mysql查詢數(shù)據(jù),改造為word模板所需的數(shù)據(jù)結(jié)構(gòu)
        List<String> stateListFromMySQL = Arrays.asList("本人所遞交的所有辦理人才引進(jìn)材料及填寫的情況均屬實(shí);"
                , "我已認(rèn)真閱讀以上內(nèi)容并確認(rèn);"
                , "若在申請(qǐng)期間信息變更不做變更。若違反,本人愿意承擔(dān)由此產(chǎn)生的后果。");
        for (int i = 0; i < stateListFromMySQL.size(); i++) {
            HashMap<String, Object> stateItem = new HashMap<>();
            // 此處在 每行文字后,都添加\n 的換行符。注意:此換行僅僅只是換行,并不等同于enter,不會(huì)觸發(fā)類似于 <在word中enter換行,自動(dòng)觸發(fā)編排序號(hào)累加> 的動(dòng)作
            stateItem.put("item", stateListFromMySQL.get(i) + "\n");
            stateList.add(stateItem);
        }
        // 從網(wǎng)絡(luò)url 下載word模板到指定文件夾
        File wordTemplate = HttpUtil.downloadFileFromUrl("http://" + ip + ":8080/file/download" + "?id=talentsTemplate.docx", "D://upload" + File.separator);
        // 此處使用了poi-tl的<表格行循環(huán)插件>,此處一定要進(jìn)行參數(shù)bind,方便word模板參數(shù)替換
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure build = Configure.builder().bind(policy, "工作經(jīng)歷列表").build();
        // 進(jìn)行編譯
        XWPFTemplate render = XWPFTemplate.compile(wordTemplate.getAbsolutePath(), build).render(finalMap);
        File word = new File("D://upload" + File.separator + IdUtil.getSnowflake().nextId() + ".docx");
        try {
            // 關(guān)鍵步驟,
            render.writeToFile(word.getAbsolutePath());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 下面的方法可以根據(jù)業(yè)務(wù)調(diào)整,我這里是將參數(shù)替換后的word上傳到項(xiàng)目對(duì)應(yīng)的文件服務(wù)器,拿到的url進(jìn)行存入數(shù)據(jù)庫(kù)
        String json = HttpUtil.createPost("http://" + ip + ":8080/file/upload")
                .header("Content-Type", ContentType.MULTIPART.getValue())
                .form("file", word)
                .execute()
                .body();
        // hutool工具類,刪除 word。因?yàn)樵谶@個(gè)流程中,word只是一個(gè)中間產(chǎn)物,因?yàn)槲疑线呉呀?jīng)把該word 上傳到我的文件服務(wù)器,并且文件服務(wù)器 會(huì)返回給我它對(duì)應(yīng)的url
        FileUtil.del(word);
        List<String> list = JSONUtil.parseArray(json).toList(String.class);
    }

2.2 根據(jù)本地文件流生成word

    /**
     * 根據(jù)本地文件流生成word
     **/
    public static void generateByFile() {
        // 此處直接是本地文件的絕對(duì)路徑
        String pictureUrl = "C://Users//x//Desktop//博客//word模板填參//generate//sign.png";
        HashMap<String, Object> finalMap = new HashMap<>();
        finalMap.put("姓名", "張三");
        finalMap.put("身份證號(hào)", "511232XXXXXXX");
        finalMap.put("手機(jī)號(hào)", "1328292xxxx");
        finalMap.put("員工簽字", "張三");
        finalMap.put("日期", "2023-05-16");
        // 從本地讀取圖片,置入word模板,等待編譯
        if (Validator.isNotEmpty(pictureUrl)) {
            PictureRenderData picture = Pictures.ofLocal(pictureUrl).size(60, 50).create();
            finalMap.put("員工簽字圖片", picture);
        }
        ArrayList<Object> workList = CollUtil.newArrayList();
        finalMap.put("工作經(jīng)歷列表", workList);
        for (int i = 0; i < 3; i++) {
            // 模擬從mysql查詢列表數(shù)據(jù)
            HashMap<String, Object> workItem = new HashMap<>();
            workItem.put("序號(hào)", i + 1);
            workItem.put("公司名", "成都有限公司" + i);
            workItem.put("工作時(shí)長(zhǎng)", i + 5 + "小時(shí)");
            workItem.put("salary", "1000" + i);
            workItem.put("聯(lián)系", "聯(lián)系人" + i);
            workItem.put("崗位", "崗位" + i);
            workList.add(workItem);
        }
        // 注意:此處用的是 <區(qū)塊對(duì)> key是字符串,value則放置一個(gè)集合,類似于模板引擎的foreach標(biāo)簽
        ArrayList<Object> stateList = CollUtil.newArrayList();
        finalMap.put("申明項(xiàng)列表", stateList);
        // 模擬從mysql查詢數(shù)據(jù),改造為word模板所需的數(shù)據(jù)結(jié)構(gòu)
        List<String> stateListFromMySQL = Arrays.asList("本人所遞交的所有辦理人才引進(jìn)材料及填寫的情況均屬實(shí);"
                , "我已認(rèn)真閱讀以上內(nèi)容并確認(rèn);"
                , "若在申請(qǐng)期間信息變更不做變更。若違反,本人愿意承擔(dān)由此產(chǎn)生的后果。");
        for (int i = 0; i < stateListFromMySQL.size(); i++) {
            HashMap<String, Object> stateItem = new HashMap<>();
            stateItem.put("item", stateListFromMySQL.get(i) + "");
            stateList.add(stateItem);
        }
        // 從網(wǎng)絡(luò)url 下載word模板到指定文件夾
        File wordTemplate = new File("C://Users//x//Desktop//博客//word模板填參//talentsTemplate.docx");
        // 此處使用了poi-tl的<表格行循環(huán)插件>,此處一定要進(jìn)行參數(shù)bind,方便word模板參數(shù)替換
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure build = Configure.builder().bind(policy, "工作經(jīng)歷列表").build();
        // 進(jìn)行編譯
        String absolutePath = wordTemplate.getAbsolutePath();
        XWPFTemplate render = XWPFTemplate.compile(absolutePath, build).render(finalMap);
        // 此處是利用File,直接在本地創(chuàng)建文件,將參數(shù)替換后的文件流寫入到該文件,word就是最終的結(jié)果
        File word = new File("C://Users//x//Desktop//博客//word模板填參//generate" + File.separator + IdUtil.getSnowflake().nextId() + ".docx");
        try {
            render.writeToFile(word.getAbsolutePath());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 下面的方法可以根據(jù)業(yè)務(wù)調(diào)整,我這里是將參數(shù)替換后的word上傳到項(xiàng)目對(duì)應(yīng)的文件服務(wù)器,拿到的url進(jìn)行存入數(shù)據(jù)庫(kù)
//        FileUtil.del(word);
//        List<String> list = JSONUtil.parseArray(json).toList(String.class);
    }

2.3 方法調(diào)用

    public static void main(String[] args) {
//        generateByNetWork();
        generateByFile();
    }

總結(jié): 上面的備注已經(jīng)說(shuō)的很清楚了,這邊不做過(guò)多解釋。如果有哪里看不懂的,評(píng)論區(qū)評(píng)論,我有空就來(lái)給你解答。

3. 基本介紹

此處不做api介紹,只做基本概念介紹,不需要的可以跳過(guò)了!官網(wǎng) http://deepoove.com/poi-tl/

poi-tl(poi template language)是Word模板引擎,使用Word模板和數(shù)據(jù)創(chuàng)建很棒的Word文檔。

方案移植性功能性易用性
Poi-tlJava跨平臺(tái)Word模板引擎,基于Apache POI,提供更友好的API低代碼,準(zhǔn)備文檔模板和數(shù)據(jù)即可
Apache POIJava跨平臺(tái)Apache項(xiàng)目,封裝了常見的文檔操作,也可以操作底層XML結(jié)構(gòu)文檔不全,這里有一個(gè)教程:Apache POI Word快速入門
FreemarkerXML跨平臺(tái)僅支持文本,很大的局限性不推薦,XML結(jié)構(gòu)的代碼幾乎無(wú)法維護(hù)
OpenOffice部署OpenOffice,移植性較差-需要了解OpenOffice的API
HTML瀏覽器導(dǎo)出依賴瀏覽器的實(shí)現(xiàn),移植性較差HTML不能很好的兼容Word的格式,樣式糟糕-
Jacob、winlibWindows平臺(tái)-復(fù)雜,完全不推薦使用

3.1 功能介紹

3.2 版本說(shuō)明

本文博客使用的是poi-tl最新版,需要apache poi 5.1.0+,不然會(huì)報(bào)錯(cuò),no such method

3.3 快速開始

依賴引入

maven
<dependency>
  <groupId>com.deepoove</groupId>
  <artifactId>poi-tl</artifactId>
  <version>1.12.1</version>
</dependency>
gradle
implementation 'com.deepoove:poi-tl:1.12.1'

官網(wǎng)demo示例

XWPFTemplate template = XWPFTemplate.compile("template.docx").render(
  new HashMap<String, Object>(){{
    put("title", "Hi, poi-tl Word模板引擎");
}});  
template.writeAndClose(new FileOutputStream("output.docx")); 

基本就是三部曲:

  • compile 編譯模板
  • render 渲染數(shù)據(jù)
  • write 輸出到流
    TDO模式:Template + data-model = output

最后再次貼出官網(wǎng)鏈接,http://deepoove.com/poi-tl/#_why_poi_tl

總結(jié)

到此這篇關(guān)于java如何根據(jù)提供word模板導(dǎo)出word文檔的文章就介紹到這了,更多相關(guān)java導(dǎo)出word文檔內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java8生成時(shí)間方式及格式化時(shí)間的方法實(shí)例

    Java8生成時(shí)間方式及格式化時(shí)間的方法實(shí)例

    這篇文章主要給大家介紹了關(guān)于Java8生成時(shí)間方式及格式化時(shí)間的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Java處理多API請(qǐng)求的方法詳解

    Java處理多API請(qǐng)求的方法詳解

    Java?中的并發(fā)是指語(yǔ)言并行運(yùn)行多個(gè)線程的能力,允許同時(shí)執(zhí)行多個(gè)任務(wù),
    2023-10-10
  • Struts2學(xué)習(xí)教程之輸入校驗(yàn)示例詳解

    Struts2學(xué)習(xí)教程之輸入校驗(yàn)示例詳解

    這篇文章主要給大家介紹了關(guān)于Struts2學(xué)習(xí)教程之輸入校驗(yàn)的相關(guān)資料,文中通過(guò)示例介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用struts2具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • java連接orcale數(shù)據(jù)庫(kù)示例分享

    java連接orcale數(shù)據(jù)庫(kù)示例分享

    這篇文章主要介紹了java連接orcale數(shù)據(jù)庫(kù)示例,需要的朋友可以參考下
    2014-02-02
  • 基于javaMybatis存進(jìn)時(shí)間戳的問(wèn)題

    基于javaMybatis存進(jìn)時(shí)間戳的問(wèn)題

    這篇文章主要介紹了javaMybatis存進(jìn)時(shí)間戳的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • SpringBoot多租戶配置與實(shí)現(xiàn)示例

    SpringBoot多租戶配置與實(shí)現(xiàn)示例

    本文詳細(xì)介紹了在SpringBoot中實(shí)現(xiàn)多租戶架構(gòu)的方法和步驟,包括配置數(shù)據(jù)源、Hibernate攔截器、租戶解析器等,以共享數(shù)據(jù)庫(kù)、共享數(shù)據(jù)表的方式,確保數(shù)據(jù)隔離和安全性,感興趣的可以了解一下
    2024-09-09
  • SpringBoot集成selenium實(shí)現(xiàn)自動(dòng)化測(cè)試的代碼工程

    SpringBoot集成selenium實(shí)現(xiàn)自動(dòng)化測(cè)試的代碼工程

    Selenium?是支持web?瀏覽器自動(dòng)化的一系列工具和[庫(kù)]?它提供了擴(kuò)展來(lái)模擬用戶與瀏覽器的交互,用于擴(kuò)展瀏覽器分配的分發(fā),本文給大家介紹了SpringBoot集成selenium實(shí)現(xiàn)自動(dòng)化測(cè)試的代碼工程,需要的朋友可以參考下
    2024-08-08
  • java設(shè)計(jì)日歷可視化的詳細(xì)步驟記錄

    java設(shè)計(jì)日歷可視化的詳細(xì)步驟記錄

    這篇文章主要給大家介紹了關(guān)于java設(shè)計(jì)日歷可視化的相關(guān)資料,通過(guò)自定義的CircleLabel類來(lái)突出顯示今天的日期,并使用BorderLayout布局管理窗口組件,文章詳細(xì)描述了各個(gè)類和方法的設(shè)計(jì)思想和實(shí)現(xiàn)邏輯,需要的朋友可以參考下
    2024-12-12
  • 解決idea報(bào)錯(cuò) Connot resolve column 的問(wèn)題

    解決idea報(bào)錯(cuò) Connot resolve column 的問(wèn)題

    這篇文章主要介紹了解決idea報(bào)錯(cuò) Connot resolve column 的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • MyBatis-Plus多數(shù)據(jù)源的示例代碼

    MyBatis-Plus多數(shù)據(jù)源的示例代碼

    本文主要介紹了MyBatis-Plus多數(shù)據(jù)源的示例代碼,包括依賴配置、數(shù)據(jù)源配置、Mapper 和 Service 的定義,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05

最新評(píng)論