使用freemarker模板引擎生成word文档的开发步骤
1、准备模板文档,如果word文档中有表格,只保留表头和第一行数据;
2、定义变量,将word文档中的变量用${var_name}替换;
3、生成xml文件,将替换变量符后的word文档另存为xml文件;
4、格式化xml文件,使用工具(XmlFormat.exe),自动生成格式化后的xml文件;
5、美化xml文件,${}中的内容仅保留变量名;
6、表格,将表格中的行数据用相应的变量替换,在第一行数据的收尾加标签:<#list tbl1 as tbl1></#list> ,注意:表格可嵌套循环
7、开发后端代码,参考《简单示例》。注意改写Bo中表格属性的getter方法,若想使用标签对数字进行有效数字的控制,那么toGetMap方法返回的数据就不能为字符串。
private List<RiskReportMonth> tabledata109 = new ArrayList<RiskReportMonth>(); public List<RiskReportMonth> getTabledata109() { return tabledata109; } publicvoid setTabledata109(RiskReportMonth tabledata109) { this.tabledata109.add(tabledata109); }
简单示例:
1、页面展示:点击查询,生成WORD,弹出下载框(没有进度条)
2、对应JS:调用controller中的方法,当没有数据时给予提示
queryRiskReport:function(){ var viewSelf = this; var year = $(\'#year\').val(); var month = $(\'#month\').val(); $.ajax({ type:\'GET\', url:$$ctx + "/riskMonthReport/searchByCondition",//程序生成word data:{ year:$(\'#year\').val(), month:$(\'#month\').val(), }, success:function(result){ if(result.data){ //生成word另存为 //window.location.href=$$ctx + "/riskMonthReport/download?outFileName="+result.data.outFileName; window.location.href=$$ctx + "/riskMonthReport/download?outFileName="+result.data.outFileName; }else{ bootbox.alert("<span style=\'font-size:16px;\'>文件未生成.</span>"); } } }); },
3、对应controller:searchByCondition():根据年月旬生成word文档(存在于程序指定的目录下), download():生成word文档另存为,让用户自定义文档下载路径
@RequestMapping(value="/searchByCondition") @ResponseBody public Result searchByCondition(String year, String month){ String condition = year + month; //获得Bo格式的数据 RiskReportMonthBo bo = riskMonthReportService.searchByCondition(condition); try { if(bo != null){ //获得Map格式的数据 Map<String, Object> dataMap = new HashMap<String, Object>(); dataMap = riskMonthReportService.toGetMap(bo); //程序生成文件名(非汉字,易乱码) //String outFileName = bo.getOutFileName() + ".doc"; String outFileName = bo.getOutFileName() + ".doc"; //在程序里生成word FreemarkerUtils.createDoc("RiskMonthReport.xml",outFileName,dataMap); logger.info("文件名:"+outFileName); } } catch (Exception e) { e.printStackTrace(); } return success(bo); }
@RequestMapping("/download") public void download(String outFileName, HttpServletRequest req, HttpServletResponse resp){ try { String filePath = FreemarkerUtils.wordPath+File.separator + outFileName + ".doc"; logger.info("文件生成路径:"+filePath); FileUtils.downloadFile(new File(filePath), "风险月度分析报告"+ ".doc", req, resp); } catch (IOException e) { e.printStackTrace(); try { resp.sendError(HttpServletResponse.SC_NOT_FOUND, "文件未生成"); } catch (IOException e1) { e1.printStackTrace(); } } }
4、对应Service:查询数据,封装bo及map
public interface TenDaysReportService { /** * 查询数据,封装Bo * @param condition * @authorwangxy 20150718 * @return */ FactLoanReportPeriodBo searchByCondition(String condition); /** * 将BO组装成Map * @param bo * @authorwangxy 20150721 * @return */ public Map<String, Object> toGetMap(FactLoanReportPeriodBo bo); }
5、对应的业务模型类Bo:封装业务数据, 注意:改写表格的get方法
privateint companycount; // 公司数 private BigDecimal contractamt ; //放款金额 publicint getCompanycount() { returncompanycount; } publicvoid setCompanycount(int companycount) { this.companycount = companycount; } public BigDecimal getContractamt() { returncontractamt; } publicvoid setContractamt(BigDecimal contractamt) { this.contractamt = contractamt; } private List<FactLoanReportPeriod> tabledata1=new ArrayList<FactLoanReportPeriod>(); public List<FactLoanReportPeriod> getTabledata1() { returntabledata1; } publicvoid setTabledata1(FactLoanReportPeriod tabledata1) { this.tabledata1.add(tabledata1); }
6、对应的实体类:与数据库表映射