使用poi生成word文档(最全例子)

1.说明平时的项目中,我们可能需要做大量的报告。而这些报告中,有些是固定的格式,有些是需要自定义模板来生成。如果是固定的形式的,那么相对而言是比较好做的,但要是根据模板来生成报告,比如:word、Excel或PDF。这样的话,可能需要我们花点时间去解决了。这篇博客主要是带领大家学习一下,如何用poi技术来实现生成word报告。2.设计我们知道,poi的技术可以做出word、Excel、...
摘要由CSDN通过智能技术生成

1.说明

平时的项目中,我们可能需要做大量的报告。而这些报告中,有些是固定的格式,有些是需要自定义模板来生成。如果是固定的形式的,那么相对而言是比较好做的,但要是根据模板来生成报告,比如:word、Excel或PDF。这样的话,可能需要我们花点时间去解决了。这篇博客主要是带领大家学习一下,如何用poi技术来实现生成word报告。

2.设计

我们知道,poi的技术可以做出word、Excel、PDF等文件。在网上也有大量的博客是关于如何使用poi的ftl的模板来生成word、Excel、PDF。主要是思路是将某个模板(自己定义的,可以是word或Excel)上传至服务器,然后解析成对应的ftl文件,之后服务在做报告时,就可以直接拿取对应的ftl文件来生成报告。这种方式会比较灵活,现在用的也比较多。但是对于一份简单的,不需要ftl的文件来作为中间生成文件时,那么可能会比较难了。比如,接下来我们要学习的,使用word的模板作为报告模板,然后直接生成需要的报告。但是word中的所的之间的设置,如字体大小、颜色等都不能改变。这个思路大概是:用户直接设计一个word模板,然后上传至服务器,服务器将其直接保存到对应的文件夹下;在要生成报告时,直接拿word的模板来填充数据。这样,好像也不是很难,但是想想细节上的地方,可能很多东西就不好做了。接下来,我们来说说问题所在。

3.问题

我们在使用word作为一份模板时,首先要解决的时,如何向模板中定义的字段替换数据,如:{name}要换成真实的改名;其次我们如果要做表格的话,如何向word上直接画出表格;再次,表格的行列要怎么合并,多张表应该怎么复制等;最后,我们应该怎么将一比我图片插入到word中。带着这些问题,我们来一一解决。

4.开发

4.1普通文本替换

在word的文件中,我们同一个使用“{**}”来标志需要替换的文件,如{name}就是要将name的字段替换成真实的姓名。所以我们需要用正则表达式来寻找到广本的内容是否包含了“{}”。正则表达式是:\\{.+?\\}。同时,我们需要用poi提供的XWPFRun的接口来替换文本。为了使用替换后的文本可以的换行的操作。比如,我们自己定义的一行文本需要换行,笔者用“@”符号作为标签,也就是如果遇到内容含有“@”,就要实现换行。而换行是调用XWPFRun的addBreak()的方法。部分代码如下:

public void replaceParagraph(XWPFParagraph xWPFParagraph, Map<String, Object> parametersMap) {
		List<XWPFRun> runs = xWPFParagraph.getRuns();
		String xWPFParagraphText = xWPFParagraph.getText();
		String regEx = "\\{.+?\\}";
	    Pattern pattern = Pattern.compile(regEx);
	    Matcher matcher = pattern.matcher(xWPFParagraphText);//正则匹配字符串{****}

		if (matcher.find()) {
			// 查找到有标签才执行替换
			int beginRunIndex = xWPFParagraph.searchText("{", new PositionInParagraph()).getBeginRun();// 标签开始run位置
			int endRunIndex = xWPFParagraph.searchText("}", new PositionInParagraph()).getEndRun();// 结束标签
			StringBuffer key = new StringBuffer();

			if (beginRunIndex == endRunIndex) {
				// {**}在一个run标签内
				XWPFRun beginRun = runs.get(beginRunIndex);
				String beginRunText = beginRun.text();

				int beginIndex = beginRunText.indexOf("{");
				int endIndex = beginRunText.indexOf("}");
				int length = beginRunText.length();

				if (beginIndex == 0 && endIndex == length - 1) {
					// 该run标签只有{**}
					XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex);
					insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr());
					// 设置文本
					key.append(beginRunText.substring(1, endIndex));
					insertNewRun.setText(getValueBykey(key.toString(),parametersMap));
					xWPFParagraph.removeRun(beginRunIndex + 1);
				} else {
					// 该run标签为**{**}** 或者 **{**} 或者{**}**,替换key后,还需要加上原始key前后的文本
					XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex);
					insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr());
					// 设置文本
					key.append(beginRunText.substring(beginRunText.indexOf("{")+1, beginRunText.indexOf("}")));
					String textString=beginRunText.substring(0, beginIndex) + getValueBykey(key.toString(),parametersMap)
							+ beginRunText.substring(endIndex + 1);
					
					insertNewRun.setText(textString);
					xWPFParagraph.removeRun(beginRunIndex + 1);
				}

			}else {
				// {**}被分成多个run

				//先处理起始run标签,取得第一个{key}值
				XWPFRun beginRun = runs.get(beginRunIndex);
				String beginRunText = beginRun.text();
				int beginIndex = beginRunText.indexOf("{");
				if (beginRunText.length()>1  ) {
					ke
  • 22
    点赞
  • 226
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
部分代码.................. . .. .. /** * 处理动态表格 * 默认取第二行第一列的标识 * @param table * @param ctRow * @param values 需要添加的数据 */ public static void processDynamicTable(XWPFTable table, CTRow ctRow, List values) { if(values==null || values.size()==0) return; for (Iterator iterator = values.iterator(); iterator.hasNext();) { String[] value = iterator.next(); XWPFTableRow newRow = new XWPFTableRow(ctRow,table); List cells = newRow.getTableCells(); if(cells==null || cells.size()==0) return; for (int j = 0; j < cells.size(); j++) { XWPFTableCell cell = cells.get(j); cell.removeParagraph(0); if(j<=value.length) cell.setText(value[j]); } table.addRow(newRow); } } /** * 处理表格 * @param doc * @param dataMap */ public static void processTable(XWPFDocument doc, Map dataMap) { Iterator iter = doc.getTablesIterator(); while(iter.hasNext()) { XWPFTable table = iter.next(); List rows = table.getRows(); if(rows==null || rows.size()==0) continue; CTRow ctRow = null; for (int i = 0; i < rows.size(); i++) { XWPFTableRow row = rows.get(i); ctRow = (CTRow)row.getCtRow().copy(); List cells = row.getTableCells(); if(cells==null || cells.size()==0) continue; //处理标致 boolean sign = false; for (int j = 0; j < cells.size(); j++) { XWPFTableCell cell = cells.get(j); if(cell.getText()==null) continue; if(i==1 && j==0) { //取第二行第一列的值,再添加table.关键字之后与dataMap匹配,有则当动态表格处理 String key = "table."+ cell.getText(); if(dataMap.containsKey(key)) { List values = (List)dataMap.get(key); table.removeRow(1); processDynamicTable(table, ctRow, values); //更新处理标致 sign = true; break; } } if(!cell.getText().startsWith("\\$") && cell.getText().endsWith("\\$")) continue; String key = cell.getText().replaceAll("\\$", ""); if(dataMap.containsKey(key)) {
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值