国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot導(dǎo)出Word文檔的三種方式

這篇具有很好參考價(jià)值的文章主要介紹了SpringBoot導(dǎo)出Word文檔的三種方式。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

SpringBoot導(dǎo)出Word文檔的三種方式

一、導(dǎo)出方案

  • 1、直接在Java代碼里創(chuàng)建Word文檔,設(shè)置格式樣式等,然后導(dǎo)出。(略)

    • 需要的見(jiàn):https://blog.csdn.net/qq_42682745/article/details/120867432
  • 2、富文本轉(zhuǎn)換后的HTML下載為Word文檔。相當(dāng)于把HTML轉(zhuǎn)為Word導(dǎo)出

  • 3、使用模板技術(shù)導(dǎo)出。固定格式、可以寫入不同數(shù)據(jù)


    其他:

    • springboot版本:2.7.11
    • 導(dǎo)出”頁(yè)面視圖“參考:https://my.oschina.net/u/1045509/blog/1924024
    • xml格式化:https://tool.ip138.com/xml/
    • HTTP下載 常用的需要設(shè)置的MIME類型
.doc      application/msword
.dot      application/msword
 
.docx     application/vnd.openxmlformats-officedocument.wordprocessingml.document
.dotx     application/vnd.openxmlformats-officedocument.wordprocessingml.template
.docm     application/vnd.ms-word.document.macroEnabled.12
.dotm     application/vnd.ms-word.template.macroEnabled.12
 
.xls      application/vnd.ms-excel
.xlt      application/vnd.ms-excel
.xla      application/vnd.ms-excel
 
.xlsx     application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.xltx     application/vnd.openxmlformats-officedocument.spreadsheetml.template
.xlsm     application/vnd.ms-excel.sheet.macroEnabled.12
.xltm     application/vnd.ms-excel.template.macroEnabled.12
.xlam     application/vnd.ms-excel.addin.macroEnabled.12
.xlsb     application/vnd.ms-excel.sheet.binary.macroEnabled.12
 
.ppt      application/vnd.ms-powerpoint
.pot      application/vnd.ms-powerpoint
.pps      application/vnd.ms-powerpoint
.ppa      application/vnd.ms-powerpoint
 
.pptx     application/vnd.openxmlformats-officedocument.presentationml.presentation
.potx     application/vnd.openxmlformats-officedocument.presentationml.template
.ppsx     application/vnd.openxmlformats-officedocument.presentationml.slideshow
.ppam     application/vnd.ms-powerpoint.addin.macroEnabled.12
.pptm     application/vnd.ms-powerpoint.presentation.macroEnabled.12
.potm     application/vnd.ms-powerpoint.template.macroEnabled.12
.ppsm     application/vnd.ms-powerpoint.slideshow.macroEnabled.12
 
.mdb      application/vnd.ms-access

二、富文本轉(zhuǎn)換后的HTML下載為Word文檔

1、準(zhǔn)備

  • 業(yè)務(wù)需求

    • 前端使用富文本插件生成帶HTML標(biāo)簽的word文檔,然后需要下載這個(gè)word文檔。
    • 每個(gè)word文檔的格式是可變的
  • 擴(kuò)展業(yè)務(wù)需求:

    • 甚至可以去替換HTML的Word中的內(nèi)容,然后導(dǎo)出需要的文檔;缺點(diǎn):替換字符串麻煩、而且HTML的Word的標(biāo)簽還需要研究。
    • 基于上述的業(yè)務(wù)需求。建議使用模板技術(shù)導(dǎo)出(也就是“三”)
  • 參考:

    • https://my.oschina.net/u/1045509/blog/1924024
    • https://blog.csdn.net/qq_42682745/article/details/120867432
  • 導(dǎo)出結(jié)果
    SpringBoot導(dǎo)出Word文檔的三種方式

2、實(shí)現(xiàn)

2.1、導(dǎo)包

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>

2.2、HTML的word文檔

package com.cc.ewd.html;

/**
 * @author CC
 * @since 2023/4/24 0024
 */
public interface HtmlConstants {

    /**
     * 普通文檔(富文本生成的)
     */
    String HTML1 = "<h1 style=\"text-align: center;\"><strong>文章標(biāo)題</strong></h1><h1><strong>一、標(biāo)題1" +
            "</strong></h1><p><strong> &nbsp; &nbsp; &nbsp; 我是數(shù)據(jù):{NUM}</strong></p><h2><strong>" +
            "1.1、吾問(wèn)無(wú)為謂</strong></h2><table style=\"width: 100%;\">" +
            "<tbody><tr><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">序號(hào)</th>" +
            "<th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">第一列</th>" +
            "<th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">第二列</th>" +
            "<th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">第三列</th>" +
            "<th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">第四列</th>" +
            "</tr><tr><td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">1</td>" +
            "<td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">11</td>" +
            "<td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">22</td>" +
            "<td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">33</td>" +
            "<td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">44</td>" +
            "</tr><tr><td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">2</td>" +
            "<td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">11</td>" +
            "<td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">22</td>" +
            "<td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">33</td>" +
            "<td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">44</td>" +
            "</tr><tr><td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">3</td>" +
            "<td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">11</td>" +
            "<td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">22</td>" +
            "<td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">33</td>" +
            "<td colspan=\"1\" rowspan=\"1\" width=\"auto\" style=\"text-align: center;\">44</td></tr>" +
            "</tbody></table><p><br></p>";

    /**
     * 帶表格文檔(可以富文本生成,也可以使用word文檔另存為HTML文件,然后拷出來(lái))
     */
    String HTML2 = "<!--StartFragment--><div class=\"Section0\"  style=\"layout-grid:15.6000pt;\" ><h1 align=center  style=\"text-align:center;\" ><b style=\"mso-bidi-font-weight:normal\" ><span style=\"mso-spacerun:'yes';font-family:宋體;mso-ascii-font-family:Calibri;\n" +
            "mso-hansi-font-family:Calibri;mso-bidi-font-family:'Times New Roman';mso-ansi-font-weight:bold;\n" +
            "font-size:22.0000pt;mso-font-kerning:22.0000pt;\" ><font face=\"宋體\" >標(biāo)題</font></span></b><b style=\"mso-bidi-font-weight:normal\" ><span style=\"mso-spacerun:'yes';font-family:宋體;mso-ascii-font-family:Calibri;\n" +
            "mso-hansi-font-family:Calibri;mso-bidi-font-family:'Times New Roman';mso-ansi-font-weight:bold;\n" +
            "font-size:22.0000pt;mso-font-kerning:22.0000pt;\" ><o:p></o:p></span></b></h1><h2><b style=\"mso-bidi-font-weight:normal\" ><span style=\"mso-spacerun:'yes';font-family:黑體;mso-ascii-font-family:Arial;\n" +
            "mso-hansi-font-family:Arial;mso-bidi-font-family:'Times New Roman';mso-ansi-font-weight:bold;\n" +
            "font-size:16.0000pt;mso-font-kerning:1.0000pt;\" ><font face=\"黑體\" >一、段落</font><font face=\"Arial\" >1</font></span></b><b style=\"mso-bidi-font-weight:normal\" ><span style=\"mso-spacerun:'yes';font-family:Arial;mso-fareast-font-family:黑體;\n" +
            "mso-bidi-font-family:'Times New Roman';mso-ansi-font-weight:bold;font-size:16.0000pt;\n" +
            "mso-font-kerning:1.0000pt;\" ><o:p></o:p></span></b></h2><p class=MsoNormal ><span style=\"mso-spacerun:'yes';font-family:宋體;mso-ascii-font-family:Calibri;\n" +
            "mso-hansi-font-family:Calibri;mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;\n" +
            "mso-font-kerning:1.0000pt;\" ><font face=\"宋體\" >噠噠</font></span><b><span style=\"mso-spacerun:'yes';font-family:宋體;mso-ascii-font-family:Calibri;\n" +
            "mso-hansi-font-family:Calibri;mso-bidi-font-family:'Times New Roman';color:rgb(0,0,255);\n" +
            "font-weight:bold;font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><font face=\"宋體\" >噠噠噠</font></span></b><span style=\"mso-spacerun:'yes';font-family:宋體;mso-ascii-font-family:Calibri;\n" +
            "mso-hansi-font-family:Calibri;mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;\n" +
            "mso-font-kerning:1.0000pt;\" ><font face=\"宋體\" >噠</font></span><span style=\"mso-spacerun:'yes';font-family:Calibri;mso-fareast-font-family:宋體;\n" +
            "mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><o:p></o:p></span></p><h3><b style=\"mso-bidi-font-weight:normal\" ><span style=\"mso-spacerun:'yes';font-family:宋體;mso-ascii-font-family:Calibri;\n" +
            "mso-hansi-font-family:Calibri;mso-bidi-font-family:'Times New Roman';mso-ansi-font-weight:bold;\n" +
            "font-size:16.0000pt;mso-font-kerning:1.0000pt;\" ><font face=\"Calibri\" >1.1</font><font face=\"宋體\" >、表格</font></span></b><b style=\"mso-bidi-font-weight:normal\" ><span style=\"mso-spacerun:'yes';font-family:Calibri;mso-fareast-font-family:宋體;\n" +
            "mso-bidi-font-family:'Times New Roman';mso-ansi-font-weight:bold;font-size:16.0000pt;\n" +
            "mso-font-kerning:1.0000pt;\" ><o:p></o:p></span></b></h3><table class=MsoTableGrid  border=1  cellspacing=0  style=\"border-collapse:collapse;border:none;mso-border-left-alt:0.5000pt solid windowtext;\n" +
            "mso-border-top-alt:0.5000pt solid windowtext;mso-border-right-alt:0.5000pt solid windowtext;mso-border-bottom-alt:0.5000pt solid windowtext;\n" +
            "mso-border-insideh:0.5000pt solid windowtext;mso-border-insidev:0.5000pt solid windowtext;mso-padding-alt:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;\" ><tr><td width=142  valign=center  style=\"width:106.5000pt;padding:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;border-left:1.0000pt solid windowtext;\n" +
            "mso-border-left-alt:0.5000pt solid windowtext;border-right:1.0000pt solid windowtext;mso-border-right-alt:0.5000pt solid windowtext;\n" +
            "border-top:1.0000pt solid windowtext;mso-border-top-alt:0.5000pt solid windowtext;border-bottom:1.0000pt solid windowtext;\n" +
            "mso-border-bottom-alt:0.5000pt solid windowtext;\" ><p class=MsoNormal  align=center  style=\"text-align:center;\" ><span style=\"font-family:宋體;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;\n" +
            "mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><font face=\"宋體\" >序號(hào)</font></span><span style=\"font-family:Calibri;mso-fareast-font-family:宋體;mso-bidi-font-family:'Times New Roman';\n" +
            "font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><o:p></o:p></span></p></td><td width=142  valign=center  style=\"width:106.5000pt;padding:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;border-left:1.0000pt solid windowtext;\n" +
            "mso-border-left-alt:0.5000pt solid windowtext;border-right:1.0000pt solid windowtext;mso-border-right-alt:0.5000pt solid windowtext;\n" +
            "border-top:1.0000pt solid windowtext;mso-border-top-alt:0.5000pt solid windowtext;border-bottom:1.0000pt solid windowtext;\n" +
            "mso-border-bottom-alt:0.5000pt solid windowtext;\" ><p class=MsoNormal  align=center  style=\"text-align:center;\" ><span style=\"font-family:宋體;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;\n" +
            "mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><font face=\"宋體\" >列</font><font face=\"Calibri\" >1</font></span><span style=\"font-family:Calibri;mso-fareast-font-family:宋體;mso-bidi-font-family:'Times New Roman';\n" +
            "font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><o:p></o:p></span></p></td><td width=142  valign=center  style=\"width:106.5500pt;padding:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;border-left:1.0000pt solid windowtext;\n" +
            "mso-border-left-alt:0.5000pt solid windowtext;border-right:1.0000pt solid windowtext;mso-border-right-alt:0.5000pt solid windowtext;\n" +
            "border-top:1.0000pt solid windowtext;mso-border-top-alt:0.5000pt solid windowtext;border-bottom:1.0000pt solid windowtext;\n" +
            "mso-border-bottom-alt:0.5000pt solid windowtext;\" ><p class=MsoNormal  align=center  style=\"text-align:center;\" ><span style=\"font-family:宋體;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;\n" +
            "mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><font face=\"宋體\" >列</font><font face=\"Calibri\" >2</font></span><span style=\"font-family:Calibri;mso-fareast-font-family:宋體;mso-bidi-font-family:'Times New Roman';\n" +
            "font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><o:p></o:p></span></p></td><td width=142  valign=center  style=\"width:106.5500pt;padding:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;border-left:1.0000pt solid windowtext;\n" +
            "mso-border-left-alt:0.5000pt solid windowtext;border-right:1.0000pt solid windowtext;mso-border-right-alt:0.5000pt solid windowtext;\n" +
            "border-top:1.0000pt solid windowtext;mso-border-top-alt:0.5000pt solid windowtext;border-bottom:1.0000pt solid windowtext;\n" +
            "mso-border-bottom-alt:0.5000pt solid windowtext;\" ><p class=MsoNormal  align=center  style=\"text-align:center;\" ><span style=\"font-family:宋體;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;\n" +
            "mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><font face=\"宋體\" >列</font><font face=\"Calibri\" >3</font></span><span style=\"font-family:Calibri;mso-fareast-font-family:宋體;mso-bidi-font-family:'Times New Roman';\n" +
            "font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><o:p></o:p></span></p></td></tr><tr><td width=142  valign=center  style=\"width:106.5000pt;padding:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;border-left:1.0000pt solid windowtext;\n" +
            "mso-border-left-alt:0.5000pt solid windowtext;border-right:1.0000pt solid windowtext;mso-border-right-alt:0.5000pt solid windowtext;\n" +
            "border-top:none;mso-border-top-alt:0.5000pt solid windowtext;border-bottom:1.0000pt solid windowtext;\n" +
            "mso-border-bottom-alt:0.5000pt solid windowtext;\" ><p class=MsoNormal  align=center  style=\"text-align:center;\" ><span style=\"font-family:宋體;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;\n" +
            "mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><font face=\"Calibri\" >1</font></span><span style=\"font-family:Calibri;mso-fareast-font-family:宋體;mso-bidi-font-family:'Times New Roman';\n" +
            "font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><o:p></o:p></span></p></td><td width=142  valign=center  style=\"width:106.5000pt;padding:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;border-left:1.0000pt solid windowtext;\n" +
            "mso-border-left-alt:0.5000pt solid windowtext;border-right:1.0000pt solid windowtext;mso-border-right-alt:0.5000pt solid windowtext;\n" +
            "border-top:none;mso-border-top-alt:0.5000pt solid windowtext;border-bottom:1.0000pt solid windowtext;\n" +
            "mso-border-bottom-alt:0.5000pt solid windowtext;\" ><p class=MsoNormal  align=center  style=\"text-align:center;\" ><span style=\"font-family:宋體;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;\n" +
            "mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><font face=\"Calibri\" >11</font></span><span style=\"font-family:Calibri;mso-fareast-font-family:宋體;mso-bidi-font-family:'Times New Roman';\n" +
            "font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><o:p></o:p></span></p></td><td width=142  valign=center  style=\"width:106.5500pt;padding:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;border-left:1.0000pt solid windowtext;\n" +
            "mso-border-left-alt:0.5000pt solid windowtext;border-right:1.0000pt solid windowtext;mso-border-right-alt:0.5000pt solid windowtext;\n" +
            "border-top:none;mso-border-top-alt:0.5000pt solid windowtext;border-bottom:1.0000pt solid windowtext;\n" +
            "mso-border-bottom-alt:0.5000pt solid windowtext;\" ><p class=MsoNormal  align=center  style=\"text-align:center;\" ><span style=\"font-family:宋體;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;\n" +
            "mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><font face=\"Calibri\" >22</font></span><span style=\"font-family:Calibri;mso-fareast-font-family:宋體;mso-bidi-font-family:'Times New Roman';\n" +
            "font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><o:p></o:p></span></p></td><td width=142  valign=center  style=\"width:106.5500pt;padding:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;border-left:1.0000pt solid windowtext;\n" +
            "mso-border-left-alt:0.5000pt solid windowtext;border-right:1.0000pt solid windowtext;mso-border-right-alt:0.5000pt solid windowtext;\n" +
            "border-top:none;mso-border-top-alt:0.5000pt solid windowtext;border-bottom:1.0000pt solid windowtext;\n" +
            "mso-border-bottom-alt:0.5000pt solid windowtext;\" ><p class=MsoNormal  align=center  style=\"text-align:center;\" ><span style=\"font-family:宋體;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;\n" +
            "mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><font face=\"Calibri\" >33</font></span><span style=\"font-family:Calibri;mso-fareast-font-family:宋體;mso-bidi-font-family:'Times New Roman';\n" +
            "font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><o:p></o:p></span></p></td></tr></table><p class=MsoNormal ><span style=\"mso-spacerun:'yes';font-family:Calibri;mso-fareast-font-family:宋體;\n" +
            "mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><o:p>&nbsp;</o:p></span></p><p class=MsoNormal ><span style=\"mso-spacerun:'yes';font-family:Calibri;mso-fareast-font-family:宋體;\n" +
            "mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><o:p>&nbsp;</o:p></span></p><p class=MsoNormal ><span style=\"mso-spacerun:'yes';font-family:Calibri;mso-fareast-font-family:宋體;\n" +
            "mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;\" ><o:p>&nbsp;</o:p></span></p><h2><b style=\"mso-bidi-font-weight:normal\" ><span style=\"mso-spacerun:'yes';font-family:黑體;mso-ascii-font-family:Arial;\n" +
            "mso-hansi-font-family:Arial;mso-bidi-font-family:'Times New Roman';mso-ansi-font-weight:bold;\n" +
            "font-size:16.0000pt;mso-font-kerning:1.0000pt;\" ><font face=\"黑體\" >二、段落</font><font face=\"Arial\" >2</font></span></b><b style=\"mso-bidi-font-weight:normal\" ><span style=\"mso-spacerun:'yes';font-family:Arial;mso-fareast-font-family:黑體;\n" +
            "mso-bidi-font-family:'Times New Roman';mso-ansi-font-weight:bold;font-size:16.0000pt;\n" +
            "mso-font-kerning:1.0000pt;\" ><o:p></o:p></span></b></h2><p class=MsoNormal ><span style=\"mso-spacerun:'yes';font-family:宋體;mso-ascii-font-family:Calibri;\n" +
            "mso-hansi-font-family:Calibri;mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;\n" +
            "mso-font-kerning:1.0000pt;\" ><o:p>&nbsp;</o:p></span></p><p class=MsoNormal ><span style=\"mso-spacerun:'yes';font-family:宋體;mso-ascii-font-family:Calibri;\n" +
            "mso-hansi-font-family:Calibri;mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;\n" +
            "mso-font-kerning:1.0000pt;\" ><o:p>&nbsp;</o:p></span></p><p class=MsoNormal ><span style=\"mso-spacerun:'yes';font-family:宋體;mso-ascii-font-family:Calibri;\n" +
            "mso-hansi-font-family:Calibri;mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;\n" +
            "mso-font-kerning:1.0000pt;\" ><o:p>&nbsp;</o:p></span></p></div><!--EndFragment-->";

}

2.3、導(dǎo)出

  • 邏輯、注意事項(xiàng)看注釋

  • 代碼:

package com.cc.ewd.web.controller;

import com.cc.ewd.html.HtmlConstants;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/** 業(yè)務(wù)需求:前端使用富文本插件生成帶HTML標(biāo)簽的word文檔,然后需要下載這個(gè)word文檔。
 * @author CC
 * @since 2023/4/24 0024
 */
@RestController
@RequestMapping("/apachePoiExport")
public class ApachePoiExport {

  /** 將HTML內(nèi)容(富文本生成的HTML)轉(zhuǎn)換為Word文檔并下載
   * @param response HTTP響應(yīng)
   */
  @GetMapping
  public void getDoc(HttpServletResponse response) {
    String fileName = "Word文件名";
    String html = HtmlConstants.HTML2;
    //導(dǎo)出word的方法
    exportWord(fileName, html, response);
  }

  /** <p>將HTML內(nèi)容(富文本生成的HTML)轉(zhuǎn)換為Word文檔并下載(word2007之后的_docx)</p>
   *  <li>參考:https://my.oschina.net/u/1045509/blog/1924024</li>
   *  <li>參考:https://blog.csdn.net/qq_42682745/article/details/120867432</li>
   * @param fileName 文件名
   * @param html 富文本生成的HTML
   * @param response 響應(yīng)
   * @since 2023/4/25 0025
   * @author CC
   **/
  public static void exportWord(String fileName, String html, HttpServletResponse response) {
    //0、獲取富文本的html:
    // HTML內(nèi)容必須被<html><body></body></html>包裝;最好設(shè)置一下編碼格式
    // HTML在這里設(shè)置<head></head>是為了讓輸入的文檔是以"頁(yè)面視圖"。而不是"Web版式"
    String wrappedHtml =
            "<html xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n" +
                    "xmlns:w=\"urn:schemas-microsoft-com:office:word\" xmlns:m=\"http://schemas.microsoft.com/office/2004/12/omml\"\n" +
                    "xmlns=\"http://www.w3.org/TR/REC-html40\">" +
                "<head>" +
                    "<!--[if gte mso 9]><xml><w:WordDocument><w:View>Print</w:View><w:TrackMoves>false</w:TrackMoves>" +
                    "<w:TrackFormatting/><w:ValidateAgainstSchemas/><w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>" +
                    "<w:IgnoreMixedContent>false</w:IgnoreMixedContent><w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>" +
                    "<w:DoNotPromoteQF/><w:LidThemeOther>EN-US</w:LidThemeOther><w:LidThemeAsian>ZH-CN</w:LidThemeAsian>" +
                    "<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript><w:Compatibility><w:BreakWrappedTables/>" +
                    "<w:SnapToGridInCell/><w:WrapTextWithPunct/><w:UseAsianBreakRules/><w:DontGrowAutofit/><w:SplitPgBreakAndParaMark/>" +
                    "<w:DontVertAlignCellWithSp/><w:DontBreakConstrainedForcedTables/><w:DontVertAlignInTxbx/><w:Word11KerningPairs/>" +
                    "<w:CachedColBalance/><w:UseFELayout/></w:Compatibility><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>" +
                    "<m:mathPr><m:mathFont m:val=\"Cambria Math\"/><m:brkBin m:val=\"before\"/><m:brkBinSub m:val=\"--\"/>" +
                    "<m:smallFrac m:val=\"off\"/><m:dispDef/><m:lMargin m:val=\"0\"/> <m:rMargin m:val=\"0\"/><m:defJc m:val=\"centerGroup\"/>" +
                    "<m:wrapIndent m:val=\"1440\"/><m:intLim m:val=\"subSup\"/><m:naryLim m:val=\"undOvr\"/></m:mathPr></w:WordDocument>" +
                    "</xml><![endif]-->" +
                "</head>" +
                "<body>%s</body>" +
            "</html>";

    wrappedHtml = String.format(wrappedHtml, html);

    //1、將HTML轉(zhuǎn)換為Word文檔byte數(shù)組
    byte[] bytes = wrappedHtml.getBytes(StandardCharsets.UTF_8);
    try (POIFSFileSystem poifsFileSystem = new POIFSFileSystem();
         InputStream byteInputStream = new ByteArrayInputStream(bytes);
//             InputStream inputStream = new BufferedInputStream(byteInputStream);
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ){
      //2、使用ApachePoi轉(zhuǎn)換word并設(shè)置到輸出流outputStream
      DirectoryEntry directory = poifsFileSystem.getRoot();
      //WordDocument名稱不允許修改
      directory.createDocument("WordDocument", byteInputStream);
      //將Word文檔寫入POIFSFileSystem對(duì)象
      poifsFileSystem.writeFilesystem(outputStream);

      //3、①將Word文檔(輸出流outputStream)寫入HTTP響應(yīng)并下載;②也可以上傳到自己的文件服務(wù)器然后返回URL給前端下載。
      response.setCharacterEncoding("utf-8");
      //設(shè)置content-type就是告訴瀏覽器這是啥玩意兒
      //"octet-stream" :通用二進(jìn)制流;
      //"msword" :Microsoft Word文檔
      //"vnd.openxmlformats-officedocument.wordprocessingml.document" :響應(yīng)的內(nèi)容類型設(shè)置為Microsoft Word 2007及更高版本的docx格式。對(duì)應(yīng)的文件名后綴需要改成”docx“
      response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8");
      //解決跨域不顯示在header里面的問(wèn)題
      response.setHeader("Access-Control-Expose-Headers","Content-disposition");
      //"attachment":讓瀏覽器把響應(yīng)視為附件并下載
      //"inline":    讓瀏覽器打開(kāi)Word文檔而不是下載它
      response.setHeader("Content-disposition","attachment; filename=" +
              URLEncoder.encode(fileName.concat(".docx"), "UTF-8"));
      //BufferedOutputStream緩沖流:可以將數(shù)據(jù)緩存在內(nèi)存中,以減少對(duì)底層IO的調(diào)用次數(shù),從而提高性能。
      //ServletOutputStream:用于向客戶端發(fā)送數(shù)據(jù)的
      //因?yàn)樾枰獙?shù)據(jù)寫入HTTP響應(yīng),所以使用ServletOutputStream是更好的選擇。
      OutputStream out = new BufferedOutputStream(response.getOutputStream());
      out.write(outputStream.toByteArray());
      out.flush();
      out.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

}


三、使用模板技術(shù)導(dǎo)出

  • 使用Thymeleaf模板技術(shù)(推薦,也是我使用的)。也可以使用FreeMarker

  • Word文件的格式是固定

  • 可以根據(jù)需求寫入不同的數(shù)據(jù)

1、準(zhǔn)備工作

1.1、導(dǎo)包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

1.2、導(dǎo)出文件的預(yù)處理,Thymeleaf語(yǔ)法

  • 使用WPS(建議使用微軟的Word)新建一個(gè)需要導(dǎo)出Word文件

SpringBoot導(dǎo)出Word文檔的三種方式

  • 這個(gè)Word文件中,需要替換的值,最好使用單獨(dú)的格式。因?yàn)閱为?dú)的格式在HTML或者xml中才能區(qū)分

SpringBoot導(dǎo)出Word文檔的三種方式

  • 弄好Word文件,最后另存為xml格式或者HTML(單個(gè)文件)格式。就得到我們需要的xml或者HTML格式的Word文件。

SpringBoot導(dǎo)出Word文檔的三種方式

  • 使用Thymeleaf語(yǔ)法修改xml文件

    • 參考:Thymeleaf更多語(yǔ)法見(jiàn)下面:

      https://blog.csdn.net/weixin_45203607/article/details/120251923
      
      https://blog.csdn.net/guoqigengxin/article/details/108674177普通文本
      
    • 普通文本

SpringBoot導(dǎo)出Word文檔的三種方式

  • 循環(huán)

SpringBoot導(dǎo)出Word文檔的三種方式

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

SpringBoot導(dǎo)出Word文檔的三種方式

  • 條件判斷:if-else

SpringBoot導(dǎo)出Word文檔的三種方式

1.3、把處理好的xml文件放到resources下

SpringBoot導(dǎo)出Word文檔的三種方式

1.4、使用HTML的注意事項(xiàng)

  • 見(jiàn)附件:thymeleaf_3_wps.html

  • 另存為后,修改HTML的編碼格式:utf-8

SpringBoot導(dǎo)出Word文檔的三種方式

  • 設(shè)置值,直接可以設(shè)置在:font 標(biāo)簽上

SpringBoot導(dǎo)出Word文檔的三種方式

  • “頁(yè)面視圖“修改:
    • 參考導(dǎo)出頁(yè)面視圖見(jiàn):一、導(dǎo)出方案

SpringBoot導(dǎo)出Word文檔的三種方式


SpringBoot導(dǎo)出Word文檔的三種方式

2、原理

  • 可以使用xml導(dǎo)出、也可以使用HTML導(dǎo)出。
  • 導(dǎo)出前需要預(yù)處理xml
  • 可以使用下面的進(jìn)行測(cè)試、導(dǎo)出。

2.1、原理

package com.cc.ewd.web.controller;

import com.cc.ewd.vo.Msg4Vo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** thymeleaf導(dǎo)出的原理
 * @author CC
 * @since 2023/4/25 0025
 */
@RestController
@RequestMapping("/thymeleafTheoryExport")
public class ThymeleafTheoryExport {

    @Resource
    private SpringTemplateEngine springTemplateEngine;

    /** <p>原理</p>
     * <ol>
     *     <li>相當(dāng)于把word文件轉(zhuǎn)為xml或者h(yuǎn)tml,然后修改其中的值再以xml、html下載成word文件</li>
     *     <li>這個(gè)方法只能運(yùn)行一次,因?yàn)閷?duì)ClassLoaderTemplateResolver的設(shè)置是一次性的</li>
     *     <li>所以需要將ClassLoaderTemplateResolver設(shè)置成單例:配置Bean。</li>
     *     <li>doc或docx的模板別使用WPS的文檔,使用微軟的office新建word文檔,然后轉(zhuǎn)為xml或html</li>
     *     <li>可以導(dǎo)出xml、也可以導(dǎo)出html:建議使用xml</li>
     * </ol>
     */
    @GetMapping
    public void thymeleafExport(HttpServletResponse response){
        String fileName = "第一個(gè)thy的文件";

        //一、設(shè)置Thymeleaf模板
        ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
        //xml文件地址:自定義xml的文件夾:thymeleafcs/thymeleaf_1_wps.xml
        //xml文件地址:默認(rèn)放在thymeleaf下就可以讀取到
        templateResolver.setPrefix("thymeleafcs/");
        //設(shè)置文件的后綴
        templateResolver.setSuffix(".xml");
//        templateResolver.setSuffix(".html");
        templateResolver.setCharacterEncoding("utf-8");
        //模板模式:默認(rèn)是HTML。改為xml
//        templateResolver.setTemplateMode(TemplateMode.XML);
        templateResolver.setTemplateMode(TemplateMode.HTML);
        //加載模板
        springTemplateEngine.setTemplateResolver(templateResolver);
        //啟用Spring EL編譯器
        springTemplateEngine.setEnableSpringELCompiler(true);

        //二、設(shè)置數(shù)據(jù)(可以用map,也可以用對(duì)象)
        Map<String,Object> map = new HashMap<>();
        //1普通文本參數(shù)
        map.put("msg1","我是參數(shù)1111");
        map.put("msg2","我是參數(shù)2222");
        map.put("msg3","我是參數(shù)3333");
        //2if-else參數(shù)
        map.put("thIf1","1");
        map.put("thIf2","2");

        //3循環(huán):構(gòu)建集合參數(shù),用于表格:可以是Map;可以是對(duì)象
//        List<Map<String,Object>> msg4Vos = new ArrayList<>();
        List<Msg4Vo> msg4Vos = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            //1map方式
//            Map<String,Object> map4 = new HashMap<>();
//            map4.put("l1","列1-" + i);
//            map4.put("l2","列2-" + i);
//            map4.put("l3","列3-" + i);
//            map4.put("l4","列4-" + i);
//            msg4Vos.add(map4);
            //2對(duì)象方式
            Msg4Vo vo = new Msg4Vo();
            vo.setL1("列1-" + i);
            vo.setL2("列2-" + i);
            vo.setL3("列3-" + i);
            vo.setL4("列4-" + i);
            msg4Vos.add(vo);
        }
        map.put("msg4Vos",msg4Vos);

        //4設(shè)置數(shù)據(jù)
        Context context = new Context();
        context.setVariables(map);
        //寫入輸入(模板名稱,數(shù)據(jù))
        String process = springTemplateEngine.process("thymeleaf_4_wps_final", context);

        //三、下載
        //建議下載成doc的。不然微軟的office可能打不開(kāi)
        try {
            byte[] bytes = process.getBytes(StandardCharsets.UTF_8);
//            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
//            ByteArrayOutputStream outputStream = getByteArrayOutputStream(inputStream);

            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            response.setHeader("Access-Control-Expose-Headers","Content-disposition");
            response.setHeader("Content-disposition","attachment; filename=" +
                    URLEncoder.encode(fileName.concat(".doc"), "UTF-8"));
            ServletOutputStream out = response.getOutputStream();

            //兩種方式都可以:用bytes好些
//            out.write(outputStream.toByteArray());
            out.write(bytes);
            out.flush();
            out.close();
        }catch(Exception e){
            e.printStackTrace();
        }

    }

    /** 將 ByteArrayInputStream 拷貝成 ByteArrayOutputStream
     *  將 字節(jié)數(shù)組輸入流 拷貝成 字節(jié)數(shù)組輸出流
     */
    public static ByteArrayOutputStream getByteArrayOutputStream(ByteArrayInputStream inputStream) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, length);
        }
        return outputStream;
    }

}

2.2、導(dǎo)出后預(yù)覽

SpringBoot導(dǎo)出Word文檔的三種方式

3、SpringBoot實(shí)現(xiàn)Thymeleaf導(dǎo)出Word

3.1、yml配置

server:
  port: 5555

spring:
  #thymeleaf的配置
  thymeleaf:
    #關(guān)閉 Thymeleaf 的緩存開(kāi)發(fā)過(guò)程中無(wú)需重啟
    #Thymeleaf默認(rèn)會(huì)開(kāi)啟頁(yè)面緩存,提高頁(yè)面并發(fā)能力。但會(huì)導(dǎo)致我們修改頁(yè)面不會(huì)立即被展現(xiàn),因此我們關(guān)閉緩存
    cache: false
    #設(shè)置thymeleaf頁(yè)面的編碼
    encoding: UTF-8
    #模型:XML/HTML5:HTML是默認(rèn)值, 為了清楚起見(jiàn), 在此處添加。
    mode: XML
    #設(shè)置thymeleaf頁(yè)面的后綴:.html是默認(rèn)。
    suffix: .xml
    #設(shè)置thymeleaf頁(yè)面的存儲(chǔ)路徑
    prefix: classpath:/thymeleafcs/
    #使用Spring 4.2.4或更高版本啟用SpringEL編譯器
    #可以加快大多數(shù)情況下的執(zhí)行速度, 但是當(dāng)一個(gè)模板中
    #的表達(dá)式在不同數(shù)據(jù)類型之間重用時(shí),
    #可能與特定情況不兼容, 因此該標(biāo)志默認(rèn)為“false”
    #以實(shí)現(xiàn)更安全的向后兼容性。
    enable-spring-el-compiler: true

3.2、實(shí)現(xiàn)

package com.cc.ewd.web.controller;

import com.cc.ewd.vo.Msg4Vo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** thymeleaf導(dǎo)出的實(shí)現(xiàn)
 * @author CC
 * @since 2023/5/4 0025
 */
@RestController
@RequestMapping("/thymeleafExport")
public class ThymeleafExport {

    @Resource
    private SpringTemplateEngine springTemplateEngine;

    /** <p>原理</p>
     * <ol>
     *     <li>相當(dāng)于把word文件轉(zhuǎn)為xml或者h(yuǎn)tml,然后修改其中的值再以xml、html下載成word文件</li>
     *     <li>這個(gè)方法只能運(yùn)行一次,因?yàn)閷?duì)ClassLoaderTemplateResolver的設(shè)置是一次性的</li>
     *     <li>所以需要將ClassLoaderTemplateResolver設(shè)置成單例:配置Bean。</li>
     *     <li>doc或docx的模板別使用WPS的文檔,使用微軟的office新建word文檔,然后轉(zhuǎn)為xml或html</li>
     *     <li>可以導(dǎo)出xml、也可以導(dǎo)出html:建議使用xml</li>
     * </ol>
     */
    @GetMapping
    public void thymeleafExport(HttpServletResponse response){
        String fileName = "第二個(gè)thy的文件";

        //一、設(shè)置數(shù)據(jù)(可以用map,也可以用對(duì)象)
        Map<String,Object> map = new HashMap<>();
        //1普通文本參數(shù)
        map.put("msg1","我是參數(shù)1111");
        map.put("msg2","我是參數(shù)2222");
        map.put("msg3","我是參數(shù)3333");
        //2if-else參數(shù)
        map.put("thIf1","1");
        map.put("thIf2","2");

        //3循環(huán):構(gòu)建集合參數(shù),用于表格:可以是Map;可以是對(duì)象
//        List<Map<String,Object>> msg4Vos = new ArrayList<>();
        List<Msg4Vo> msg4Vos = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            //1map方式
//            Map<String,Object> map4 = new HashMap<>();
//            map4.put("l1","列1-" + i);
//            map4.put("l2","列2-" + i);
//            map4.put("l3","列3-" + i);
//            map4.put("l4","列4-" + i);
//            msg4Vos.add(map4);
            //2對(duì)象方式
            Msg4Vo vo = new Msg4Vo();
            vo.setL1("列1-" + i);
            vo.setL2("列2-" + i);
            vo.setL3("列3-" + i);
            vo.setL4("列4-" + i);
            msg4Vos.add(vo);
        }
        map.put("msg4Vos",msg4Vos);

        //4設(shè)置數(shù)據(jù)
        Context context = new Context();
        context.setVariables(map);
        //寫入輸入(模板名稱,數(shù)據(jù))
        String process = springTemplateEngine.process("thymeleaf_4_wps_final", context);

        //二、下載
        //建議下載成doc的。不然微軟的office可能打不開(kāi)
        try {
            byte[] bytes = process.getBytes(StandardCharsets.UTF_8);
//            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
//            ByteArrayOutputStream outputStream = getByteArrayOutputStream(inputStream);

            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            response.setHeader("Access-Control-Expose-Headers","Content-disposition");
            response.setHeader("Content-disposition","attachment; filename=" +
                    URLEncoder.encode(fileName.concat(".doc"), "UTF-8"));
            ServletOutputStream out = response.getOutputStream();

            //兩種方式都可以:用bytes好些
//            out.write(outputStream.toByteArray());
            out.write(bytes);
            out.flush();
            out.close();
        }catch(Exception e){
            e.printStackTrace();
        }

    }

    /** 將 ByteArrayInputStream 拷貝成 ByteArrayOutputStream
     *  將 字節(jié)數(shù)組輸入流 拷貝成 字節(jié)數(shù)組輸出流
     */
    public static ByteArrayOutputStream getByteArrayOutputStream(ByteArrayInputStream inputStream) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, length);
        }
        return outputStream;
    }

}

3.3、不使用yml配置,使用配置bean方式

  • 可以配置不同的bean,注入使用的時(shí)候,使用我們需要的bean。實(shí)現(xiàn):動(dòng)態(tài)使用不同的模板導(dǎo)出。
  • 如果yml中配置了, 又配置了bean。yml中的配置會(huì)失效。
  • 其中一個(gè)bean一定要添加:@Primary。來(lái)設(shè)置默認(rèn)的bean
  • config配置
package com.cc.ewd.config;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.templatemode.TemplateMode;

import javax.annotation.Resource;

/** ThymeLeaf單獨(dú)的配置
 * @since 2023/5/4 0004
 * @author CC
 **/
@Configuration
public class MyThymeLeafConfig {

    @Resource
    private ApplicationContext applicationContext;

    /** 自定義的bean
     * @return SpringTemplateEngine
     * @Primary :<li>作用:指定使用名為“myTemplateEngine”的bean作為默認(rèn)bean。</li>
     *          <li>這樣,當(dāng)您在需要使用SpringTemplateEngine的地方?jīng)]有指定@Qualifier注釋時(shí),Spring將使用該默認(rèn)bean。</li>
     *          <li>使用@Resource時(shí),可直接設(shè)置名字。不用使用@Qualifier注釋</li>
     */
    @Bean(name = "myTemplateEngine")
    @Primary
    public SpringTemplateEngine myTemplateEngine(){
        // SpringTemplateEngine自動(dòng)應(yīng)用SpringStandardDialect
        // 并啟用Spring自己的MessageSource消息解析機(jī)制。
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        SpringResourceTemplateResolver templateResolver = myTemplateResolver();
        templateEngine.setTemplateResolver(templateResolver);
        // 使用Spring 4.2.4或更高版本啟用SpringEL編譯器
        // 可以加快大多數(shù)情況下的執(zhí)行速度, 但是當(dāng)一個(gè)模板中
        // 的表達(dá)式在不同數(shù)據(jù)類型之間重用時(shí),
        // 可能與特定情況不兼容, 因此該標(biāo)志默認(rèn)為“false”
        // 以實(shí)現(xiàn)更安全的向后兼容性。
        templateEngine.setEnableSpringELCompiler(true);
        return templateEngine;
    }

    /** 自定義配置
     * @return SpringResourceTemplateResolver
     */
    @Bean("myTemplateResolver")
    public SpringResourceTemplateResolver myTemplateResolver(){
        // SpringResourceTemplateResolver自動(dòng)與Spring自己集成
        // 資源解決基礎(chǔ)設(shè)施, 強(qiáng)烈推薦。
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setApplicationContext(this.applicationContext);
        templateResolver.setPrefix("classpath:thymeleafcs/");
        templateResolver.setSuffix(".html");
        templateResolver.setCharacterEncoding("UTF-8");
        // HTML是默認(rèn)值, 為了清楚起見(jiàn), 在此處添加。
        templateResolver.setTemplateMode(TemplateMode.HTML);
        return templateResolver;
    }

//----------------------------------------------

    /** 自定義的bean2
     * @return SpringTemplateEngine
     */
    @Bean(name = "myTemplateEngine2")
    public SpringTemplateEngine myTemplateEngine2(){
        // SpringTemplateEngine自動(dòng)應(yīng)用SpringStandardDialect
        // 并啟用Spring自己的MessageSource消息解析機(jī)制。
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        SpringResourceTemplateResolver templateResolver = myTemplateResolver2();
        templateEngine.setTemplateResolver(templateResolver);
        // 使用Spring 4.2.4或更高版本啟用SpringEL編譯器
        // 可以加快大多數(shù)情況下的執(zhí)行速度, 但是當(dāng)一個(gè)模板中
        // 的表達(dá)式在不同數(shù)據(jù)類型之間重用時(shí),
        // 可能與特定情況不兼容, 因此該標(biāo)志默認(rèn)為“false”
        // 以實(shí)現(xiàn)更安全的向后兼容性。
        templateEngine.setEnableSpringELCompiler(true);
        return templateEngine;
    }

    /** 自定義配置2
     * @return SpringResourceTemplateResolver
     */
    @Bean("myTemplateResolver2")
    public SpringResourceTemplateResolver myTemplateResolver2(){
        // SpringResourceTemplateResolver自動(dòng)與Spring自己集成
        // 資源解決基礎(chǔ)設(shè)施, 強(qiáng)烈推薦。
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setApplicationContext(this.applicationContext);
        templateResolver.setPrefix("classpath:thymeleafcs/");
        templateResolver.setSuffix(".xml");
        templateResolver.setCharacterEncoding("UTF-8");
        // HTML是默認(rèn)值, 為了清楚起見(jiàn), 在此處添加。
        templateResolver.setTemplateMode(TemplateMode.XML);
        return templateResolver;
    }

}
  • 使用

    • @Resource注入:

          @Resource(name = "myTemplateEngine")
          private SpringTemplateEngine springTemplateEngine;
      
    • @Autowired注入:

          @Autowired
          @Qualifier("myTemplateEngine")
          private SpringTemplateEngine springTemplateEngine1Html;
      
    • 配置文件會(huì)失效——配置類優(yōu)先

    • 使用:根據(jù)傳入的type不同。使用的模板是不同的。

package com.cc.ewd.web.controller;

import com.cc.ewd.vo.Msg4Vo;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** thymeleaf導(dǎo)出的實(shí)現(xiàn)
 * @author CC
 * @since 2023/5/4 0025
 */
@RestController
@RequestMapping("/thymeleafExport")
public class ThymeleafExport {

//    @Resource
//    private SpringTemplateEngine springTemplateEngine;
    @Resource(name = "myTemplateEngine")
    private SpringTemplateEngine springTemplateEngine1Html;
    @Resource(name = "myTemplateEngine2")
    private SpringTemplateEngine springTemplateEngine2Xml;

    /** <p>原理</p>
     * <ol>
     *     <li>相當(dāng)于把word文件轉(zhuǎn)為xml或者h(yuǎn)tml,然后修改其中的值再以xml、html下載成word文件</li>
     *     <li>這個(gè)方法只能運(yùn)行一次,因?yàn)閷?duì)ClassLoaderTemplateResolver的設(shè)置是一次性的</li>
     *     <li>所以需要將ClassLoaderTemplateResolver設(shè)置成單例:配置Bean。</li>
     *     <li>doc或docx的模板別使用WPS的文檔,使用微軟的office新建word文檔,然后轉(zhuǎn)為xml或html</li>
     *     <li>可以導(dǎo)出xml、也可以導(dǎo)出html:建議使用xml</li>
     * </ol>
     */
    @GetMapping
    public void thymeleafExport(@RequestParam String type, HttpServletResponse response){
        String fileName = "第二個(gè)thy的文件";

        //一、設(shè)置數(shù)據(jù)(可以用map,也可以用對(duì)象)
        Map<String,Object> map = new HashMap<>();
        //1普通文本參數(shù)
        map.put("msg1","我是參數(shù)1111");
        map.put("msg2","我是參數(shù)2222");
        map.put("msg3","我是參數(shù)3333");
        //2if-else參數(shù)
        map.put("thIf1","1");
        map.put("thIf2","2");

        //3循環(huán):構(gòu)建集合參數(shù),用于表格:可以是Map;可以是對(duì)象
//        List<Map<String,Object>> msg4Vos = new ArrayList<>();
        List<Msg4Vo> msg4Vos = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            //1map方式
//            Map<String,Object> map4 = new HashMap<>();
//            map4.put("l1","列1-" + i);
//            map4.put("l2","列2-" + i);
//            map4.put("l3","列3-" + i);
//            map4.put("l4","列4-" + i);
//            msg4Vos.add(map4);
            //2對(duì)象方式
            Msg4Vo vo = new Msg4Vo();
            vo.setL1("列1-" + i);
            vo.setL2("列2-" + i);
            vo.setL3("列3-" + i);
            vo.setL4("列4-" + i);
            msg4Vos.add(vo);
        }
        map.put("msg4Vos",msg4Vos);

        //4設(shè)置數(shù)據(jù)
        Context context = new Context();
        context.setVariables(map);
        //寫入輸入(模板名稱,數(shù)據(jù)):1:html;2:xml
        String process = "";
        if ("1".equals(type)){
            process = springTemplateEngine1Html.process("thymeleaf_3_wps", context);
        }else if ("2".equals(type)){
            process = springTemplateEngine2Xml.process("thymeleaf_4_wps_final", context);
        }

        //二、下載
        //建議下載成doc的。不然微軟的office可能打不開(kāi)
        try {
            byte[] bytes = process.getBytes(StandardCharsets.UTF_8);
//            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
//            ByteArrayOutputStream outputStream = getByteArrayOutputStream(inputStream);

            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            response.setHeader("Access-Control-Expose-Headers","Content-disposition");
            response.setHeader("Content-disposition","attachment; filename=" +
                    URLEncoder.encode(fileName.concat(".doc"), "UTF-8"));
            ServletOutputStream out = response.getOutputStream();

            //兩種方式都可以:用bytes好些
//            out.write(outputStream.toByteArray());
            out.write(bytes);
            out.flush();
            out.close();
        }catch(Exception e){
            e.printStackTrace();
        }

    }

    /** 將 ByteArrayInputStream 拷貝成 ByteArrayOutputStream
     *  將 字節(jié)數(shù)組輸入流 拷貝成 字節(jié)數(shù)組輸出流
     */
    public static ByteArrayOutputStream getByteArrayOutputStream(ByteArrayInputStream inputStream) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, length);
        }
        return outputStream;
    }

}

四、總結(jié)

  • 甚至可以結(jié)合Thymeleaf模板技術(shù)和ApachePoi技術(shù)。
  • 先使用Thymeleaf模板技術(shù)替換Word文檔中的值。然后得到完整的HTML格式的Word文檔
  • 然后使用ApachePoi導(dǎo)出HTML格式的Word文檔
  • 文中使用到的文檔:

https://files.cnblogs.com/files/blogs/787464/SpringBoot導(dǎo)出Word文檔的三種方式-文檔.rar?t=1683184411&download=true文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-433379.html

到了這里,關(guān)于SpringBoot導(dǎo)出Word文檔的三種方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • springboot依賴注入的三種方式

    springboot依賴注入的三種方式 在 Spring Boot 中,使用 XML 配置依賴注入(DI)時(shí),需要使用 bean 元素來(lái)定義 bean,并使用 property 元素來(lái)為 bean 的屬性注入值或依賴對(duì)象。 以下是一個(gè)簡(jiǎn)單的示例: 在 src/main/resources 目錄下創(chuàng)建 applicationContext.xml 文件。 在該文件中定義一個(gè) testBean

    2023年04月23日
    瀏覽(25)
  • 【SpringBoot】獲取HttpServletRequest的三種方式

    線程安全 缺點(diǎn): 每個(gè)方法都需要寫一遍 線程安全 在 Spring 中, DemoRequestController 的 scope 是 singleton (單例),也就是說(shuō)在整個(gè) web 系統(tǒng)中,只有一個(gè) DemoRequestController ;但是其中注入的 request 卻是線程安全的,原因在于:使用這種方式,當(dāng) Bean (本例的 DemoRequestController )初始化

    2024年02月12日
    瀏覽(20)
  • SpringBoot實(shí)現(xiàn)分頁(yè)的三種方式

    一 自己封裝Page對(duì)象實(shí)現(xiàn) 博客鏈接 二 使用sql實(shí)現(xiàn)分頁(yè) 2.1 場(chǎng)景分析 前段傳遞給給后臺(tái)什么參數(shù)? 當(dāng)前頁(yè)碼 currentPage 每頁(yè)顯示條數(shù) pageSize 后臺(tái)給前端返回什么數(shù)據(jù)? 當(dāng)前頁(yè)數(shù)據(jù) List 總記錄數(shù) totalCount 2.2 前段代碼 2.3 后端代碼 PageBean mapper service impl controller 三 使用PageHelper插件

    2024年02月10日
    瀏覽(28)
  • 【SpringBoot18】SpringBoot 調(diào)用外部接口的三種方式

    【SpringBoot18】SpringBoot 調(diào)用外部接口的三種方式

    SpringBoot不僅繼承了Spring框架原有的優(yōu)秀特性,而且還通過(guò)簡(jiǎn)化配置來(lái)進(jìn)一步簡(jiǎn)化了Spring應(yīng)用的整個(gè)搭建和開(kāi)發(fā)過(guò)程。在Spring-Boot項(xiàng)目開(kāi)發(fā)中,存在著本模塊的代碼需要訪問(wèn)外面模塊接口,或外部url鏈接的需求, 比如在apaas開(kāi)發(fā)過(guò)程中需要封裝接口在接口中調(diào)用apaas提供的接口(

    2023年04月11日
    瀏覽(35)
  • Java 將word轉(zhuǎn)為PDF的三種方式和處理在服務(wù)器上下載后亂碼的格式

    Java 將word轉(zhuǎn)為PDF的三種方式和處理在服務(wù)器上下載后亂碼的格式

    我這邊是因?yàn)闃I(yè)務(wù)需要將之前導(dǎo)出的word文檔轉(zhuǎn)換為PDF文件,然后頁(yè)面預(yù)覽下載這樣的情況。之前導(dǎo)出word文檔又不是我做的,所以為了不影響業(yè)務(wù),只是將最后在輸出流時(shí)轉(zhuǎn)換成了PDF,當(dāng)時(shí)本地調(diào)用沒(méi)什么問(wèn)題,一切正常,后面發(fā)布測(cè)試環(huán)境使用時(shí)才發(fā)現(xiàn),導(dǎo)出時(shí)PDF文件內(nèi)容

    2024年02月03日
    瀏覽(27)
  • SpringBoot獲取HttpServletRequest、HttpServletResponse的三種方式

    SpringBoot獲取HttpServletRequest、HttpServletResponse的三種方式

    僅僅適用在controller方法上。當(dāng)Spring接收到HTTP請(qǐng)求時(shí),會(huì)尋找一個(gè)合適的方法來(lái)處理該請(qǐng)求。如果該方法參數(shù)上標(biāo)注了@RequestMapping或@Get、@Post等注解,Spring就會(huì)將HttpServletRequest對(duì)象注入到該參數(shù)中。 適用于所有的bean 通過(guò)調(diào)試可以看到,注入的Reques是一個(gè)代理類,而這個(gè)被代

    2024年02月19日
    瀏覽(25)
  • Springboot中使用線程池的三種方式

    前言 多線程是每個(gè)程序員的噩夢(mèng),用得好可以提升效率很爽,用得不好就是埋汰的火葬場(chǎng)。 這里不深入介紹,主要是講解一些標(biāo)準(zhǔn)用法,熟讀唐詩(shī)三百首,不會(huì)作詩(shī)也會(huì)吟。 這里就介紹一下springboot中的多線程的使用,使用線程連接池去異步執(zhí)行業(yè)務(wù)方法。 由于代碼中包含詳

    2024年02月08日
    瀏覽(24)
  • SpringBoot獲取Request請(qǐng)求的三種方式

    Request對(duì)象包含了請(qǐng)求的各種信息,比如請(qǐng)求方法、請(qǐng)求URL、請(qǐng)求參數(shù)、請(qǐng)求內(nèi)容等等,這些信息可以供服務(wù)器進(jìn)行處理和響應(yīng)。那么在SpringBoot中,怎么才能獲取到Request對(duì)象? 本文將介紹三種方法,并提示例參考。 一、直接在Controller方法參數(shù)上注入HttpServletRequest 這是最常用

    2024年02月04日
    瀏覽(25)
  • SpringBoot實(shí)現(xiàn)過(guò)濾器Filter的三種方式

    SpringBoot實(shí)現(xiàn)過(guò)濾器Filter的三種方式

    過(guò)濾器 Filter 由 Servlet 提供,基于函數(shù)回調(diào)實(shí)現(xiàn)鏈?zhǔn)綄?duì)網(wǎng)絡(luò)請(qǐng)求與響應(yīng)的攔截與修改。由于基于 Servlet ,其可以對(duì)web服務(wù)器管理的幾乎所有資源進(jìn)行攔截(JSP、圖片文件、HTML 文件、CSS文件等)。 Filter 的生命周期 init(): 初始化Filter 實(shí)例,F(xiàn)ilter 的生命周期與 Servlet 是相同的,

    2024年02月14日
    瀏覽(17)
  • SpringBoot+MyBatis批量插入數(shù)據(jù)的三種方式

    最近導(dǎo)入表格數(shù)據(jù)時(shí)需要同時(shí)插入修改大量數(shù)據(jù),研究了一下有三種實(shí)現(xiàn)方式 1、用for循環(huán)調(diào)用sql插入數(shù)據(jù) 這種方式插入大量數(shù)據(jù)時(shí),效率非常底下,不推薦 2、利用mybatis的foreach來(lái)實(shí)現(xiàn)循環(huán)插入 這種方式插入大量數(shù)據(jù)時(shí),好處是不用頻繁訪問(wèn)數(shù)據(jù)庫(kù),一條sql搞定,效率比較

    2024年02月16日
    瀏覽(20)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包