java使用freemarker模板导出word,合并单元格,单元格内换行
? ? ? ?之前使用XWPFDocument動態寫入word,XWPFDocument不支持2003,word2003需要用HWPFDocument,HWPFDocument對于動態生成行效果不是很好,所以使用freemarker動態生成,生成的支持所有格式。
一、使用officeword建一個需要的表格,需要動態替換的可以先寫上字母
二、另存為word2003xml格式
三、把后綴修改為ftl
四、把word xml格式化,可以使用notepad++的xml tool插件,或者使用在線格式化
格式化前
格式化后
五、把之前所有要替換的字母加${}
改為
六、需要動態添加的找到<w:tr>,在<w:tr>上加<#list postdutyNormList as postdutyNormObj>
循環里面的字母加上${postdutyNormObj.}
七、合并單元格
例合并5行的第一列,第一行的第一列有值,增加<w:vmerge w:val="restart"/>;第二、三、四、五行的第一列沒值把<w:r></w:r>去掉,增加<w:vmerge/>
第一行:
第二、三、四、五行:
動態判斷如下:其中index是行號
八、內容相同的上下行合并,其中preContent是上一行的值,可以在java里添加需要判斷列的值
九、單元格內換行
在java里循環,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是所有要替換的內容
/**** @Date 2019年2月25日 下午17:30:23* @Description 考核成績匯總導出考核表具體條目* @Fcunction exportWordForSpecific* @param response* @return ReturnDatas**/@ResponseBody@SystemControllerLog(description="考核成績匯總導出考核表具體條目")@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("考核成績匯總導出考核表具體條目異常:"+e.getMessage(),e);returnDatas.setStatus(ReturnDatas.ERROR);returnDatas.setMessage("考核成績匯總導出考核表具體條目異常。");}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中需要展示的動態數據* @param templateName word模板名稱* @param output 輸出流* @return* @throws IOException * @throws TemplateException */public static void createDoc(Map<?, ?> dataMap,String templateName,OutputStream output) throws TemplateException, IOException {//創建配置實例 Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);//設置編碼configuration.setDefaultEncoding("UTF-8");//空值configuration.setClassicCompatible(true);//ftl模板文件統一放至 com.fh.template 包下面configuration.setClassForTemplateLoading(WordGenerator.class,"/templates/");//獲取模板 Template template = configuration.getTemplate(templateName);//將模板和數據模型合并生成文件 Writer out = new BufferedWriter(new OutputStreamWriter(output,"UTF-8"));// 這個地方不能使用FileWriter因為需要指定編碼類型否則生成的Word文檔會因為有無法識別的編碼而無法打開 // Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8"); //生成文件template.process(dataMap, out);//關閉流out.flush();out.close();} }十二、參考
注:若動態替換的內容里有特殊符號,如"<>",可以是用?html轉義。在freemarker模板里把${content}改成${content?html}
標簽相關
<w:tr></w:tr>:每一行;
<w:tc></w:tc>:是每一列;
<w:p></w:p>:控制單元格內換行;
<w:tcPr></w:tcPr>:里面添加合并;
<w:r></w:r>:里面是內容樣式及內容;
<w:t></w:t>:里面是內容;
${assessAllObj.content?html}:如果替換的內容里有<>會報錯,可以加上?html進行轉義
常用到的語句
<#list postdutyNormList as postdutyNormObj> </#if> <#if postdutyNormObj.index==1><w:vmerge w:val="restart"/> <#else><w:vmerge/> </#if>?
總結
以上是生活随笔為你收集整理的java使用freemarker模板导出word,合并单元格,单元格内换行的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Excel知识技能] 排序功能
- 下一篇: 通俗易懂了解50个IT专业术语