1.背景
在项目中有个需求是将查询出的领用借出单实现打印功能.一般的实现思路是先将领用单导出成word,再将其转成pdf,上传到ftp(这一步看需求可以替换成本地或者其他地方)获取地址,将地址返回给前端.前端得到这个利用浏览器自带的pdf的打印功能,实现打印.
2.编写导出成word模板(以领用单为例)
注:在替换过程中${receiveNo}可能不会被替换,如果 出现这种情况,是模板有问题,将${receiveNo}整个复制到txt,再复制回去即可.
3.controller层
/** * 打印预览--先导出成docx,在上传到ftp,得到ftp地址进行显示 */ @RequestMapping(value = "/printPreview/{appId}", method = {RequestMethod.POST, RequestMethod.GET }) @ResponseBody public WebResponse printPreview( HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "appId", required = false) String appId, @RequestParam(value = "receiveNo", required = false) String receiveNo ){ Pager pager; Map<String, Object> map = new HashMap<>(); try { String path = request.getSession().getServletContext().getRealPath("/") + "rpt_template" + "/" + "word" + "/" + "receiveInfo.docx"; String newPath = request.getSession().getServletContext().getRealPath("/") + "rpt_template" + "/" + "word" + "/" + "receiveInfoNW.docx"; Integer page = 1; Integer rows = 99; pager = receiveService.getReceiveInfo(receiveNo, page, rows); FileUtils.copyFile(new File(newPath), new File(path)); CustomXWPFDocument doc = receiveService.receiveInfoPdf(pager.getRows(), path); map = receiveService.handlePdf(request, doc); } catch (Exception e) { e.printStackTrace(); return this.buildResponse("705", e.getMessage()); } return buildResponse(map); }
注:模板要保存两份,不然会出现上次导出的会累加,所以要用新的模板替换.
4.service层(service层主要替换模板信息)
public CustomXWPFDocument receiveInfoPdf(List<ReceiveInfoResult> info,String wordPath){ Map<String, Object> data = new HashMap<>(); data.put("${receiveNo}", info.get(0).getReceiveNo()); data.put("${sectionName}", info.get(0).getSectionName()); data.put("${receiveName}", info.get(0).getReceiveName()); data.put("${receiveTime}", info.get(0).getReceiveTime()); List<Map<String, Object>> receiveInfoList = new ArrayList<Map<String, Object>>(); for (int i = 0; i < info.size(); i++) { ReceiveInfoResult receiveInfo = info.get(i); Map<String, Object> content = new HashMap<>(); content.put("序号", String.valueOf(i + 1)); content.put("工器具类型", receiveInfo.getInstrumentTypeBig()); content.put("工器具名称", receiveInfo.getInstrumentName()); content.put("规格型号", receiveInfo.getInstrumentModel()); content.put("RFID编码", receiveInfo.getRfid()); content.put("位置", receiveInfo.getContainerNumber()); content.put("归还时间", receiveInfo.getInTime()); content.put("状态", receiveInfo.getInState()); receiveInfoList.add(content); } data.put("${contentList}", receiveInfoList); CustomXWPFDocument doc = WorderToNewWordUtils.changWordReceiveInfo(wordPath, data); return doc; }
5.其中用到的主要的util类
根据领用单模板生成word文档
/** * 根据领用单模板生成word文档 * @param inputUrl 模板路径 * @param textMap 需要替换的文本内容 * @return */ public static CustomXWPFDocument changWordReceiveInfo(String inputUrl, Map<String, Object> textMap) { CustomXWPFDocument document = null; try { //获取docx解析对象 document = new CustomXWPFDocument(POIXMLDocument.openPackage(inputUrl)); //解析替换文本段落对象 try { WorderToNewWordUtils.changeText(document,textMap); } catch (Exception e) { e.printStackTrace(); } //解析替换表格对象 WorderToNewWordUtils.changeTableReceive(document,textMap); } catch (IOException e) { e.printStackTrace(); } return document; }
替换表格对象方法
/** * 替换表格对象方法 * @param document docx解析对象 * @param textMap 需要替换的信息集合 */ public static void changeTableReceive(CustomXWPFDocument document, Map<String, Object> textMap){ //获取表格对象集合 List<XWPFTable> tables = document.getTables(); //动态添加 问题列表行 XWPFTable table1 = tables.get(0);//获取第一个表格 // XWPFTableRow table1 = tables.get(0).getRow(0); List<Map<String, Object>> contentList = (List<Map<String, Object>>) textMap.get("${contentList}"); if (contentList != null && contentList.size()>0){ for(int i=0;i<contentList.size();i++){ XWPFTableRow row = table1.insertNewTableRow(1+i);//为第2+i行向下添加一个新行 //XWPFTableRow row = table1; row.createCell().setText((String) contentList.get(i).get("序号"));//添加第二个列 row.createCell().setText((String) contentList.get(i).get("工器具类型"));//添加第三个列 row.createCell().setText((String) contentList.get(i).get("工器具名称"));//添加第四个列 row.createCell().setText((String) contentList.get(i).get("规格型号"));//添加第五个列 row.createCell().setText((String) contentList.get(i).get("RFID编码"));//添加第五个列 row.createCell().setText((String) contentList.get(i).get("位置"));//添加第五个列 row.createCell().setText((String) contentList.get(i).get("归还时间"));//添加第五个列 row.createCell().setText((String) contentList.get(i).get("状态"));//添加第五个列 } } }
转换成pdf,上传到ftp
/** * * @param request * @param doc * @return 获取PDF路径 * @throws Exception */ public Map<String,Object> handlePdf(HttpServletRequest request, CustomXWPFDocument doc) throws Exception { //生成地址 创建PDF路径 生成wordPath 开始 String newWordPath = request.getSession().getServletContext().getRealPath("/") + "rpt_template/temp_file/" + UUID.randomUUID().toString() + ".docx"; File newFile = new File(newWordPath); newFile.createNewFile();//新增一个文件 FileOutputStream fopts = new FileOutputStream(newFile); doc.write(fopts); fopts.close(); doc.close(); //生成wordPath 结束 //创建返回map Map<String, Object> resultMap = new HashMap<>(); //创建PDF路径 String pdfTeamPath = request.getSession().getServletContext().getRealPath("/") + "rpt_template" + "/" + "temp_file" + "/" + UUID.randomUUID() + ".pdf"; //word形式转换成pdf(fileUrl文件路径/pdfTeamPath转PDF路径) FileUtil.doc2pdf(newWordPath, pdfTeamPath); //上传ftp 服务器 File pdfFile = new File(pdfTeamPath); String pdfPath = FTPUtil.uploadFile("files/pdf/", pdfFile, pdfFile.getName()); String pdfUrl = ConstantsUtil.photoPath + pdfPath; //获取路径 resultMap.put("fileUrl", pdfUrl); //删除文件 pdfTeamPath ExportSafetyNoticeRest.deleteFile(pdfTeamPath); ExportSafetyNoticeRest.deleteFile(newWordPath); resultMap.put("worfUrl", newWordPath); return resultMap; }
end!