在使用jacob和jacob工具类将html页面导出到word时自己最后遇见了效率低下的问题,也想方设法做了一些代码的改进,更多的是使用了工具类FileUtils.java。
导致效率低下的主要原因是创建、打开word(操作一次将近两秒),当然还有一些其他的文件读写等【图片的创建、html写入word、word写入response】
1.在WEB-INF创建:文件夹blank-template,里面有一个空白的word文档。
2.【改进】程序:
/** * 获取存有每张图片datURL的数组,创建图片,返回临时文件夹名和每张图片名 * * @param imgs * @return * @throws IOException */ @ResponseBody @RequestMapping("/exportWord") public void exportWord(HttpServletRequest request, HttpServletResponse response) throws IOException { String html = request.getParameter("html"); String imgs = request.getParameter("imgs"); String uuid = ""; String localpath = request.getSession().getServletContext().getRealPath("WEB-INF"); try { // 生成uuid作为临时文件夹名称,防止多并发创建同名img文件 uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase(); String docName = getWord(imgs, html, localpath, uuid); // 写入浏览器 docName = docName + ".doc"; String filepath = localpath + File.separator + uuid + File.separator + docName; File complete = new File(filepath); // 向浏览器发送文件下载,支持断点续传 FileUtils.downFile(complete, request, response, docName); } catch (Exception e) { e.printStackTrace(); } finally { // 清空临时文件夹 FileUtils.deleteDirectory(localpath + File.separator + uuid); } } /** * 创建空白文档_写入html_复制空白文档至临时文档_处理临时文档image_复制临时文档至最终文档 * * @param imgs * @param html * @param localpath */ public String getWord(String imgs, String html, String localpath, String uuid) { Document document = null; String temppath = localpath + File.separator + "blank-template"; localpath = localpath + File.separator + uuid; // 复制系统已经预先创建好的文件夹【含有blank.doc】 FileUtils.copyDirectoryCover(temppath, localpath + File.separator, true); net.sf.json.JSONObject imgsObj = net.sf.json.JSONObject.fromObject(imgs); // 处理ajax传来的字符串 JSONArray imgsJson = imgsObj.getJSONArray("echartArr"); // 创建图片,获取图片-地址集合 Map<String, String> imgMap = createImg(localpath, imgsJson); // 解析html_创建空白文档_html写入空白文档 document = Jsoup.parse(html); // 将html写入blank.doc文件 FileUtils.writeToFile(localpath + File.separator + "blank.doc", document.html(), false); String complete = "统计分析系统" + DateUtils.getDate(); // 复制空白文档-粘贴到临时文档(相当于手动执行copy_paste) MSOfficeGeneratorUtils officeUtils = new MSOfficeGeneratorUtils(false); officeUtils.openDocument(localpath + File.separator + "blank.doc"); officeUtils.copy(); // 拷贝整篇文档 officeUtils.close(); officeUtils.createNewDocument(); officeUtils.paste(); // 粘贴整篇文档 // 将图片${image_name}替换为真实图片 for (Entry<String, String> entry : imgMap.entrySet()) officeUtils.replaceText2Image(entry.getKey(), entry.getValue()); officeUtils.setFont(true, false, false, "0,0,0", "20", "宋体"); // 设置字体,具体参数 officeUtils.saveAs(localpath + File.separator + complete + ".doc"); // 生成D:UUID.doc文件,利用UUID防止同名 officeUtils.close(); // 关闭Office Word创建的文档 officeUtils.quit(); // 退出Office Word程序 imgMap.clear(); return complete; } /** * 将base64转化为图片 * * @param localpath * @param imgsJson * 图片在文档中的键${name} - 值图片的绝对路径 * @return */ public Map<String, String> createImg(String localpath, JSONArray imgsJson) { Map<String, String> imgMap = new HashMap<String, String>(); for (Object object : imgsJson) { String name = ((net.sf.json.JSONObject) object).getString("name"); String imgDataURL = ((net.sf.json.JSONObject) object).getString("imgDataURL"); String imgPath = localpath + File.separator + name; String type = CommonUtils.GenerateImage(imgPath, imgDataURL); imgMap.put("${" + name + "}", imgPath + "." + type); } return imgMap; }
我仅仅只是少创建了一个空白word【花两秒】,而是使用copy一个空白文档的方式【花200毫秒】节省了将近两秒。可能还有更好的办法,暂且记录。