java使用POI根据word模板生成文档,并且根据参数值实现换行

本文介绍如何利用Java的POI库,结合Word模板,通过替换参数值来生成新的Word文档,详细步骤包括定义模板、设置参数映射及生成文档。

一,word模板如下

二,将word模板中的参数对应的值放到map中

/**
	 * 将word模板中需要的参数值统一放到map中
	 * 
	 * @param resource
	 * @param template
	 * @param job
	 * @return
	 */
	public Map<String, String> getWordTemplateParam(ExtractResources resource) {
		ExtractJobs extractJob = jobsDao.findById(job.getId()).get();
		String statisticsInfo = this.formatStatistic(extractJob.getStatisticsInfo());

		Map<String, String> params = new HashMap<String, String>();
		params.put("data", statisticsInfo);
		params.put("DataReceivingUnit", resource.getOrganization());
		params.put("SubjectOrProject", resource.getTopic());
	
		return params;
	}

/**
	 * 需要根据\n换行的参数值
	 * @param statisticsInfo
	 * @return
	 */
	public String formatStatistic(String statisticsInfo) {
		String result = "";

		String bcmStr = "";
		String subDocTypeStr = "";
		Map<String, Integer> map = (Map) JSON.parse(statisticsInfo);
		Set<Entry<String, Integer>> entrySet = map.entrySet();
		for (Entry<String, Integer> entry : entrySet) {
			String key = entry.getKey();
			Integer value = entry.getValue();
			if (Pattern.matches("^[a-zA-Z]+$", key)) {
				// 母体类型
				String keyStr;
				//省略业务代码
				keyStr = key;
				
				bcmStr += keyStr + ":" + value + "\n";//这里标识以\n为标识,表名明需要换行
			} else {
				// 子类型
				subDocTypeStr += key + " : " + value + "\n";
			}

		}

		result = result + subDocTypeStr + bcmStr;

		return result;
	}

三,根据模板生成word文档


/**
 * 生成word文档
 */
public void addStatisticWord(ExtractResources resource, ExtractTemplate template, ExtractJobs job) {
	OutputStream os = null;
	InputStream is = null;
	Map<String, String> params = this.getWordTemplateParam(resource,template,job);
	try {
		// word文档模板路径
		String filePath = "D:" + File.separator + "templateWord" + File.separator + "数据模板.docx";
		File templateFile = new File(filePath);
		if (!templateFile.exists()) {
			templateFile.mkdirs();
		}

		// 输出的word文件名称
		String outputName = "NSTL数据交接登记表-" + template.getTemplateName() + "-" + job.getId() + ".docx";

		// word输出路径 resourcPath/jobId/success
		String outputPath = resource.getFileSavePath() + File.separator + job.getId() + File.separator + "success"+ File.separator + outputName;

		is = new FileInputStream(templateFile);
		XWPFDocument doc = new XWPFDocument(is);
		List<XWPFTable> tables = doc.getTables();// 获取全部表格对象(word模板是一个表格)
		for (XWPFTable xwpfTable : tables) {
			List<XWPFTableRow> rows = xwpfTable.getRows();// 获取word模板表格每一行
			for (XWPFTableRow row : rows) {
				List<XWPFTableCell> tableCells = row.getTableCells();//每一行的单元格
				for (XWPFTableCell cell : tableCells) {
					List<XWPFParagraph> paragraphs = cell.getParagraphs();// 每个单元格里的段落集合
					for (XWPFParagraph paragraph : paragraphs) {
						String paragraphText = paragraph.getText();
						if (this.checkText(paragraphText)) {
							//段落文字包含$,代表是参数,需要替换为map中对应的参数值
							List<XWPFRun> runs = paragraph.getRuns();
							for (int i = 0; i < runs.size(); i++) {
								XWPFRun run = runs.get(i);
								String runText = this.changeValue(run.toString(), params);//根据参数名到map中获取参数值
								paragraph.removeRun(i);//可以理解为删除当前这一个段落
								run = paragraph.insertNewRun(i);//然后插入一个新的段落
								// 设置字体
								run.setFontFamily("黑体");
								run.setFontSize(14);
								if (runText.contains("\n")) {
									//参数值包含\n代表需要换行(也可以设置成\r,只是一个标识,因为我在formatStatistic方法中设置的以\n为标识换行)
									String[] text = runText.split("\n");
									for (int j = 0; j < text.length; j++) {
										run.setText(text[j].trim());//往新的段落里set参数值
										run.addBreak();// 换行
									}
								} else {
									run.setText(runText);
								}
							}
						}
					}
				}
			}
		}
		os = new FileOutputStream(outputPath);
		doc.write(os);

	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		this.close(os);
		this.close(is);
	}

}

    /**
	 * 匹配传入信息集合与模板
	 * 
	 * @param value   模板需要替换的区域
	 * @param textMap 传入信息集合
	 * @return 模板需要替换区域信息集合对应值
	 */
	public String changeValue(String value, Map<String, String> textMap) {
		Set<Entry<String, String>> textSets = textMap.entrySet();
		for (Entry<String, String> textSet : textSets) {
			// 匹配模板与替换值 格式${key}
			String key = "${" + textSet.getKey() + "}";
			if (value.indexOf(key) != -1) {
				value = textSet.getValue();
			}
		}
		// 模板未匹配到区域替换为空
		if (checkText(value)) {
			value = "";
		}
		return value;
	}

	/**
	 * 判断文本中时候包含$
	 * 
	 * @param text 文本
	 * @return 包含返回true,不包含返回false
	 */
	public boolean checkText(String text) {
		boolean check = false;
		if (text.indexOf("$") != -1) {
			check = true;
		}
		return check;

	}

    /**
	 * 关闭输入流
	 * 
	 * @param is
	 */
	private void close(InputStream is) {
		if (is != null) {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 关闭输出流
	 * 
	 * @param os
	 */
	private void close(OutputStream os) {
		if (os != null) {
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值