日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java使用freemarker模板导出word,合并单元格,单元格内换行

發(fā)布時(shí)間:2023/12/8 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java使用freemarker模板导出word,合并单元格,单元格内换行 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? ? ? ?之前使用XWPFDocument動(dòng)態(tài)寫入word,XWPFDocument不支持2003,word2003需要用HWPFDocument,HWPFDocument對(duì)于動(dòng)態(tài)生成行效果不是很好,所以使用freemarker動(dòng)態(tài)生成,生成的支持所有格式。

一、使用officeword建一個(gè)需要的表格,需要?jiǎng)討B(tài)替換的可以先寫上字母

二、另存為word2003xml格式

三、把后綴修改為ftl

四、把word xml格式化,可以使用notepad++的xml tool插件,或者使用在線格式化

格式化前

格式化后

五、把之前所有要替換的字母加${}

改為

六、需要?jiǎng)討B(tài)添加的找到<w:tr>,在<w:tr>上加<#list postdutyNormList as postdutyNormObj>

循環(huán)里面的字母加上${postdutyNormObj.}

七、合并單元格

例合并5行的第一列,第一行的第一列有值,增加<w:vmerge w:val="restart"/>;第二、三、四、五行的第一列沒值把<w:r></w:r>去掉,增加<w:vmerge/>

第一行:

第二、三、四、五行:

動(dòng)態(tài)判斷如下:其中index是行號(hào)

八、內(nèi)容相同的上下行合并,其中preContent是上一行的值,可以在java里添加需要判斷列的值

九、單元格內(nèi)換行

在java里循環(huán),trs就是替換的count

for (int i = 0; i < count; i++) {VPersonalWorkDailyChild tr = list_p.get(i);VPersonalWorkDaily parent = baseInfoService.getObjectById(VPersonalWorkDaily.class, tr.getId_personal_work_daily());String data = i+1+". "+gfnull(tr.getTime())+" "+gfnull(parent.getName_place())+gfnull(tr.getPlace())+" "+gfnull(tr.getContent());trs += "<w:p wsp:rsidR=\"00000000\" wsp:rsidRDefault=\"008F1A6A\">"+"<w:pPr>"+"<w:jc w:val=\"left\"/>"+"<w:rPr>"+"<w:sz w:val=\"20\"/>"+"</w:rPr>"+"</w:pPr>"+"<w:r>"+"<w:rPr>"+"<w:rFonts w:hint=\"fareast\"/>"+"<w:sz w:val=\"20\"/>"+"</w:rPr>"+"<w:t>"+data+"</w:t>"+"</w:r>"+"</w:p>"; }

十、Controller代碼,map是所有要替換的內(nèi)容

/**** @Date 2019年2月25日 下午17:30:23* @Description 考核成績(jī)匯總導(dǎo)出考核表具體條目* @Fcunction exportWordForSpecific* @param response* @return ReturnDatas**/@ResponseBody@SystemControllerLog(description="考核成績(jī)匯總導(dǎo)出考核表具體條目")@RequestMapping(value="exportWordForSpecific")public ReturnDatas exportWordForSpecific(HttpServletResponse response, String id){ReturnDatas returnDatas = ReturnDatas.getSuccessReturnDatas();try {Map<String, Object> map = assessGradeSumService.exportWordForSpecific(id);String org_name = (String) map.get("org_name");String user_name = (String) map.get("user_name");String month_ = (String) map.get("month_");response.setCharacterEncoding("UTF-8");response.setContentType("application/msexcle");response.setHeader("content-disposition", "attachment;filename="+new String((org_name+"-"+user_name+month_+"履職考核表").getBytes("utf-8"),"ISO8859-1")+".doc");OutputStream outputStream = response.getOutputStream();WordGenerator.createDoc(map, "AssessMonthTable2.ftl", outputStream);outputStream.flush();outputStream.close();returnDatas.setStatus(ReturnDatas.SUCCESS);return returnDatas;} catch (Exception e) {e.printStackTrace();LogUtil.error("考核成績(jī)匯總導(dǎo)出考核表具體條目異常:"+e.getMessage(),e);returnDatas.setStatus(ReturnDatas.ERROR);returnDatas.setMessage("考核成績(jī)匯總導(dǎo)出考核表具體條目異常。");}return returnDatas;}

十一、WordGenerator 工具類

package com.enter.net.util;import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Map; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException;public class WordGenerator {/*** 生成doc文件* @param dataMap word中需要展示的動(dòng)態(tài)數(shù)據(jù)* @param templateName word模板名稱* @param output 輸出流* @return* @throws IOException * @throws TemplateException */public static void createDoc(Map<?, ?> dataMap,String templateName,OutputStream output) throws TemplateException, IOException {//創(chuàng)建配置實(shí)例 Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);//設(shè)置編碼configuration.setDefaultEncoding("UTF-8");//空值configuration.setClassicCompatible(true);//ftl模板文件統(tǒng)一放至 com.fh.template 包下面configuration.setClassForTemplateLoading(WordGenerator.class,"/templates/");//獲取模板 Template template = configuration.getTemplate(templateName);//將模板和數(shù)據(jù)模型合并生成文件 Writer out = new BufferedWriter(new OutputStreamWriter(output,"UTF-8"));// 這個(gè)地方不能使用FileWriter因?yàn)樾枰付ň幋a類型否則生成的Word文檔會(huì)因?yàn)橛袩o法識(shí)別的編碼而無法打開 // Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8"); //生成文件template.process(dataMap, out);//關(guān)閉流out.flush();out.close();} }

十二、參考

注:若動(dòng)態(tài)替換的內(nèi)容里有特殊符號(hào),如"<>",可以是用?html轉(zhuǎn)義。在freemarker模板里把${content}改成${content?html}

標(biāo)簽相關(guān)

<w:tr></w:tr>:每一行;

<w:tc></w:tc>:是每一列;

<w:p></w:p>:控制單元格內(nèi)換行;

<w:tcPr></w:tcPr>:里面添加合并;

<w:r></w:r>:里面是內(nèi)容樣式及內(nèi)容;

<w:t></w:t>:里面是內(nèi)容;

${assessAllObj.content?html}:如果替換的內(nèi)容里有<>會(huì)報(bào)錯(cuò),可以加上?html進(jìn)行轉(zhuǎn)義

常用到的語句

<#list postdutyNormList as postdutyNormObj> </#if> <#if postdutyNormObj.index==1><w:vmerge w:val="restart"/> <#else><w:vmerge/> </#if>

?

總結(jié)

以上是生活随笔為你收集整理的java使用freemarker模板导出word,合并单元格,单元格内换行的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。