开发

软件开发相关知识

Java使用aspose.word读取文档图片文字放到指定位置

需求是:从一个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;
}