需求是:从一个word文件中读取段落和图片,存放到word模板中。
代码如下:
//通过模板生成文件,保存并导出 @RequestMapping("/exportTemplate") public ResponseEntity<byte[]> exportTemplate(@RequestParam("id") Integer id, @RequestParam("files") String files, HttpServletRequest request, HttpServletResponse response) throws Exception { getLicense(); Templates template = templatesService.getById(id); String templatePath = template_path; if (template != null) { templatePath += template.getTemplateFilePath(); } else { return null; } //读取选定的模板文件的配置项 List<TemplateProperties> templatePropertiesList = templatePropertiesService.list(new QueryWrapper<TemplateProperties>() .eq("template_id", template.getId()) ); File path = new File(ResourceUtils.getURL("classpath:").getPath()); //获取模板文件的存放路径。 String templateFilesPath = path.getAbsolutePath() + templatePath; //加载模板文件 Document document = new Document(templateFilesPath); Map<String, Object> datas = new HashMap<String, Object>(); //替换模板文件中的配置项内容 if (templatePropertiesList != null && templatePropertiesList.size() > 0) { for (TemplateProperties templateProperties : templatePropertiesList) { datas.put(templateProperties.getTemplateName(), templateProperties.getPropertiesValue()); document.getRange().replace(templateProperties.getTemplateName(), templateProperties.getPropertiesValue(), false, false); } } //获取用来加载生成模板的文件 files = files.replace(",,", ","); Section[] sections = document.getSections().toArray(); //获取目录的位置和正文的位置 Run runContent = null, runTOC = null; for (Section section : sections) { //获取模板文件中的段落 Paragraph[] paragraphs = section.getBody().getParagraphs().toArray(); for (Paragraph paragraph : paragraphs) { Run[] runs = paragraph.getRuns().toArray(); for (Run run : runs) { if (run.getText().contains("{{content}}")) { runContent = run; } else if (run.getText().contains("{{toc}}")) { runTOC = run; } } } } DocumentBuilder builder = new DocumentBuilder(document); if (runContent != null) { //替换正文 builder.moveTo(runContent); for (String file : files.split(",")) { String readFilePath = path + file; FileInputStream fs = new FileInputStream(readFilePath); Document doc = new Document(fs); fs.close(); Section[] sectionFiless = doc.getSections().toArray(); int iTemp = 0; for (Section sectionFile : sectionFiless) { //获取模板文件中的段落 Paragraph[] paras = sectionFile.getBody().getParagraphs().toArray(); for (Paragraph para : paras) { boolean ifTitleFlag = false;//是否是标题,即word版式中的标题一、二等,用于最后生成目录 if (para.getParagraphFormat().getStyleName() != null) { if (para.getParagraphFormat().getStyleIdentifier() == 1) { builder.getParagraphFormat().setFirstLineIndent(0); builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); Font font = builder.getFont(); font.setSize(18); font.setColor(new Color(91, 155, 213)); //font.setColor(new Color(192, 0, 0)); font.setBold(true); builder.writeln(para.getText().trim()); ifTitleFlag = true; } else if (para.getParagraphFormat().getStyleIdentifier() == 2) { builder.getParagraphFormat().setFirstLineIndent(0); builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); Font font = builder.getFont(); font.setSize(15); font.setColor(new Color(0, 0, 0)); font.setBold(true); builder.writeln(para.getText().trim()); ifTitleFlag = true; } } if (!ifTitleFlag) { //如果不是标题,则按普通文字保存格式 builder.getParagraphFormat().setFirstLineIndent(20); builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.BODY_TEXT); Font font = builder.getFont(); font.setSize(12); font.setColor(new Color(0, 0, 0)); font.setBold(false); builder.writeln(para.getText().trim()); } //获取段落后的图片,保存到段落之后 Node[] children = para.getChildNodes().toArray(); for (Node child : children) { if (child.getNodeType() == NodeType.SHAPE) { Shape shape = (Shape) child; Image images = shape.getImageData().toImage(); builder.getParagraphFormat().setFirstLineIndent(0); builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.BODY_TEXT); builder.insertImage((BufferedImage) images); } } } } } //移除正文标志的 {{content}}标签 runContent.remove(); } if (runTOC != null) { //移动到目录位置生成目录 builder.moveTo(runTOC); builder.insertTableOfContents("\\o \"1-3\" \\h \\z \\u"); runTOC.remove(); } //更新目录的域信息 document.updateFields(); //初始化输出流 ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); //将文档以docx格式保存到输出流中 document.save(byteOut, SaveFormat.DOCX); //保存文件 String fileName = id + "_" + DateTools.getDateString(new Date()) + ".docx"; String folderDateString = DateTools.getDateDayString(new Date()); String filePath = "/statics/upload/" + folderDateString; String saveFileNamePath = filePath + "/" + id + "/" + fileName; document.save(saveFileNamePath, SaveFormat.DOCX); //开启新线程,执行保存历史记录任务 Runnable task = () -> { // 在这里执行你的任务 TemplateHistoryFiles templateHistoryFiles = new TemplateHistoryFiles(); templateHistoryFiles.setTemplateId(id); templateHistoryFiles.setFilePath(saveFileNamePath); templateHistoryFiles.setGenerateDate(DateTools.getDateToStr(new Date())); templateHistoryFiles.setGenerateUser(username); templateHistoryFiles.setPropertiesValue(JSON.toJSONString(datas)); templateHistoryFilesService.save(templateHistoryFiles); }; Thread thread = new Thread(task); thread.start(); //生成下载文件 HttpHeaders headers = new HttpHeaders(); //下载显示的文件名,并解决中文名称乱码问题 String downloadFileName = new String(fileName.getBytes(StandardCharsets.UTF_8.name()), StandardCharsets.ISO_8859_1.name()); //通知浏览器以attachment(下载方式)打开 headers.setContentDispositionFormData("attachment", downloadFileName); //applicatin/octet-stream: 二进制流数据(最常见的文件下载) headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); byte[] byteArr = byteOut.toByteArray(); return new ResponseEntity<byte[]>(byteArr, headers, HttpStatus.CREATED); } //获取aspose.words的license文件 public boolean getLicense() { boolean result = false; try { ApplicationHome home = new ApplicationHome(getClass()); File jarFile = home.getSource(); //System.out.println("=================" + jarFile.getParentFile().getParentFile().toString()); File file = new File(jarFile.getParentFile().getParentFile().toString() + "/license.xml"); if (file.exists()) { InputStream is = new FileInputStream(file); License aposeLic = new License(); aposeLic.setLicense(is); result = true; } } catch (Exception e) { //异常处理 e.printStackTrace(); } return result; }