失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > java使用freemarker模板导出word 合并单元格 单元格内换行

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

时间:2018-10-07 17:23:34

相关推荐

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

之前使用XWPFDocument动态写入word,XWPFDocument不支持,word需要用HWPFDocument,HWPFDocument对于动态生成行效果不是很好,所以使用freemarker动态生成,生成的支持所有格式。

一、使用officeword建一个需要的表格,需要动态替换的可以先写上字母

二、另存为wordxml格式

三、把后缀修改为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 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 .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 合并单元格 单元格内换行》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。