使用java Apache poi 根據word模板生成word報表

項目開發過程當中,客戶提出一堆導出報表的需求,須要導出word格式,頁眉還須要加上客戶公司的logo,試了幾種方案,最後選擇了用 Apache poi 加上自定義標籤的方式實現。html

目前功能還比較簡單,一些複雜的表格作不了,可是已經基本知足項目需求了。java

使用poi讀取word模板,替換word中的{text}標籤,並根據自定義標籤循環生成表格或表格中的行。
代碼示例下載:https://download.csdn.net/download/u012775558/10306308
注意,僅支持docx格式的word文件,大概是word2010及之後版本,doc格式不支持。apache

word模板須要有固定的格式,下面是幾個示例與代碼實現.app

基礎文本替換示例

只是最基礎的文本替換less

模板以下:

生成報表以下:

表格內部循環生成行

注意:maven

  1. 表格第一行經過合併單元格的方式,設置爲只有兩個單元格,第一個單元格填寫foreachTableRow標籤,第二個單元格填寫要替換的數據List名稱,本例中是table1或table2,注意名稱要和你後臺wordDataMap中存入的key值相同。
  2. 表格第二行是表頭。
  3. 表格第三行須要經過合併單元格的方式,設置爲只有一個單元格,填寫上foreachRows標籤,表明從這一行如下開始循環替換。
  4. 表格第四行是要替換的數據,在map中的key值。
模板以下:

生成報表以下:

能夠給表格加上表頭和表尾數據,只須要把數據放入parametersMap(存儲報表中不循環的數據)中便可。工具


表格內部行添加序號示例

你也能夠給行加上序號,可是不能直接輸入序號,而是經過word的插入編號的功能插入編號,生成的表格纔會有編號。this

模板以下:

生成報表以下:

也能夠給表格加上表頭和表尾數據,只須要把數據放入parametersMap(存儲報表中不循環的數據)中便可。spa


循環生成表格示例

注意:.net

  1. 表格第一行經過合併單元格的方式,設置爲只有兩個單元格,第一個單元格填寫foreachTable標籤,第二個單元格填寫要替換的數據List名稱,本例中是table1。
  2. 表格其餘部分只須要將要替換的數據用標籤替換便可。
模板以下:

生成報表以下


使用方法以下

使用maven搭建項目,引入poi相關jar包。

<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>3.13</version>
</dependency>
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>3.13</version>
</dependency>

代碼以下

  • 工具類 WordTemplate

/**
 * @Title: WordTemplate2.java
 * @Package: com.highdata.templateTools
 * @Description: TODO
 * @author: Juveniless
 * @date: 2017年11月27日 下午3:23:13
 */
package com.hidata.tool;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.xwpf.usermodel.BodyElementType;
import org.apache.poi.xwpf.usermodel.IBodyElement;
import org.apache.poi.xwpf.usermodel.PositionInParagraph;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;

/**
 *
 * 對docx文件中的文本及表格中的內容進行替換 --模板僅支持對 {key} 標籤的替換
 *
 * @ClassName: WordTemplate
 * @Description: TODO(!!!使用word2013 docx文件)
 * @author Juveniless
 * @date: 2017年11月27日 下午3:25:56
 * <br>(1)word模板注意頁邊距的問題,存在問題:好比頁邊距默認爲3cm,畫表格時,仍然能夠經過
 * 拖拽,把表格邊框拖動到看起來就像頁邊距只有1cm的樣子,可是實際上此時頁邊距仍是3cm,生成的
 * word報表的頁邊距仍是會按照3cm來生成。解決辦法,在word文件裏,設置好頁邊距,若是須要表格
 * 兩邊頁邊距很窄,須要在word裏設置頁邊距窄一點,而不是直接拖動表格邊框來實現。
 *
 */

public class WordTemplate {

	private XWPFDocument document;

	public XWPFDocument getDocument() {
		return document;
	}

	public void setDocument(XWPFDocument document) {
		this.document = document;
	}

	/**
	 * 初始化模板內容
	 *
	 * @author Juveniless
	 * @date 2017年11月27日 下午3:59:22
	 * @param inputStream
	 *            模板的讀取流(docx文件)
	 * @throws IOException
	 *
	 */
	public WordTemplate(InputStream inputStream) throws IOException {
		document = new XWPFDocument(inputStream);
	}

	/**
	 * 將處理後的內容寫入到輸出流中
	 *
	 * @param outputStream
	 * @throws IOException
	 */
	public void write(OutputStream outputStream) throws IOException {
		document.write(outputStream);
	}





	/**
	 * 根據dataMap對word文件中的標籤進行替換; <br><br>
	 * !!!!***須要注意dataMap的數據格式***!!!! <br><br>
	 * 對於須要替換的普通標籤數據標籤(不須要循環)-----必須在dataMap中存儲一個key爲parametersMap的map,
	 * 來存儲這些不須要循環生成的數據,好比:表頭信息,日期,製表人等。 <br><br>
	 * 對於須要循環生成的表格數據------key自定義,value爲 --ArrayList&lt;Map&lt;String, String>>
	 * @author Juveniless
	 * @date 2017年11月27日 下午3:29:27
	 * @param dataMap
	 *
	 */
	public void replaceDocument(Map<String, Object> dataMap) {

		if (!dataMap.containsKey("parametersMap")) {
			System.out.println("數據源錯誤--數據源(parametersMap)缺失");
			return;
		}
		@SuppressWarnings("unchecked")
		Map<String, Object> parametersMap = (Map<String, Object>) dataMap
				.get("parametersMap");

		List<IBodyElement> bodyElements = document.getBodyElements();// 全部對象(段落+表格)
		int templateBodySize = bodyElements.size();// 標記模板文件(段落+表格)總個數

		int curT = 0;// 當前操做表格對象的索引
		int curP = 0;// 當前操做段落對象的索引
		for (int a = 0; a < templateBodySize; a++) {
			IBodyElement body = bodyElements.get(a);
			if (BodyElementType.TABLE.equals(body.getElementType())) {// 處理表格
				XWPFTable table = body.getBody().getTableArray(curT);

				List<XWPFTable> tables = body.getBody().getTables();
				table = tables.get(curT);
				if (table != null) {

					// 處理表格
					List<XWPFTableCell> tableCells = table.getRows().get(0).getTableCells();// 獲取到模板表格第一行,用來判斷表格類型
					String tableText = table.getText();// 表格中的全部文本

					if (tableText.indexOf("##{foreach") > -1) {
						// 查找到##{foreach標籤,該表格須要處理循環
						if (tableCells.size() != 2
								|| tableCells.get(0).getText().indexOf("##{foreach") < 0
								|| tableCells.get(0).getText().trim().length() == 0) {
							System.out
									.println("文檔中第"
											+ (curT + 1)
											+ "個表格模板錯誤,模板表格第一行須要設置2個單元格,"
											+ "第一個單元格存儲表格類型(##{foreachTable}## 或者 ##{foreachTableRow}##),第二個單元格定義數據源。");
							return;
						}

						String tableType = tableCells.get(0).getText();
						String dataSource = tableCells.get(1).getText();
						System.out.println("讀取到數據源:"+dataSource);
						if (!dataMap.containsKey(dataSource)) {
							System.out.println("文檔中第" + (curT + 1) + "個表格模板數據源缺失");
							return;
						}
						@SuppressWarnings("unchecked")
						List<Map<String, Object>> tableDataList = (List<Map<String, Object>>) dataMap
								.get(dataSource);
						if ("##{foreachTable}##".equals(tableType)) {
							// System.out.println("循環生成表格");
							addTableInDocFooter(table, tableDataList, parametersMap, 1);

						} else if ("##{foreachTableRow}##".equals(tableType)) {
							// System.out.println("循環生成表格內部的行");
							addTableInDocFooter(table, tableDataList, parametersMap, 2);
						}

					} else if (tableText.indexOf("{") > -1) {
						// 沒有查找到##{foreach標籤,查找到了普通替換數據的{}標籤,該表格只須要簡單替換
						addTableInDocFooter(table, null, parametersMap, 3);
					} else {
						// 沒有查找到任何標籤,該表格是一個靜態表格,僅須要複製一個便可。
						addTableInDocFooter(table, null, null, 0);
					}
					curT++;

				}
			} else if (BodyElementType.PARAGRAPH.equals(body.getElementType())) {// 處理段落
				// System.out.println("獲取到段落");
				XWPFParagraph ph = body.getBody().getParagraphArray(curP);
				if (ph != null) {
					// htmlText = htmlText+readParagraphX(ph);
					addParagraphInDocFooter(ph, null, parametersMap, 0);

					curP++;
				}
			}

		}
		// 處理完畢模板,刪除文本中的模板內容
		for (int a = 0; a < templateBodySize; a++) {
			document.removeBodyElement(0);
		}

	}








	/**
	 * 根據 模板表格 和 數據list 在word文檔末尾生成表格
	 * @author Juveniless
	 * @date 2017年12月6日 上午10:12:05
	 * @param templateTable 模板表格
	 * @param list   循環數據集
	 * @param parametersMap  不循環數據集
	 * @param flag   (0爲靜態表格,1爲表格總體循環,2爲表格內部行循環,3爲表格不循環僅簡單替換標籤便可)
	 *
	 */
	public void addTableInDocFooter(XWPFTable templateTable, List<Map<String, Object>> list,
			Map<String, Object> parametersMap, int flag) {

		if (flag == 1) {// 表格總體循環
			for (Map<String, Object> map : list) {
				List<XWPFTableRow> templateTableRows = templateTable.getRows();// 獲取模板表格全部行
				XWPFTable newCreateTable = document.createTable();// 建立新表格,默認一行一列
				for (int i = 1; i < templateTableRows.size(); i++) {
					XWPFTableRow newCreateRow = newCreateTable.createRow();
					CopyTableRow(newCreateRow, templateTableRows.get(i));// 複製模板行文本和樣式到新行
				}
				newCreateTable.removeRow(0);// 移除多出來的第一行
				document.createParagraph();// 添加回車換行
				replaceTable(newCreateTable, map);//替換標籤
			}

		} else if (flag == 2) {// 表格表格內部行循環
			XWPFTable newCreateTable = document.createTable();// 建立新表格,默認一行一列
			List<XWPFTableRow> TempTableRows = templateTable.getRows();// 獲取模板表格全部行
			int tagRowsIndex = 0;// 標籤行indexs
			for (int i = 0, size = TempTableRows.size(); i < size; i++) {
				String rowText = TempTableRows.get(i).getCell(0).getText();// 獲取到表格行的第一個單元格
				if (rowText.indexOf("##{foreachRows}##") > -1) {
					tagRowsIndex = i;
					break;
				}
			}

			/* 複製模板行和標籤行以前的行 */
			for (int i = 1; i < tagRowsIndex; i++) {
				XWPFTableRow newCreateRow = newCreateTable.createRow();
				CopyTableRow(newCreateRow, TempTableRows.get(i));// 複製行
				replaceTableRow(newCreateRow, parametersMap);// 處理不循環標籤的替換
			}

			/* 循環生成模板行 */
			XWPFTableRow tempRow = TempTableRows.get(tagRowsIndex + 1);// 獲取到模板行
			for (int i = 0; i < list.size(); i++) {
				XWPFTableRow newCreateRow = newCreateTable.createRow();
				CopyTableRow(newCreateRow, tempRow);// 複製模板行
				replaceTableRow(newCreateRow, list.get(i));// 處理標籤替換
			}

			/* 複製模板行和標籤行以後的行 */
			for (int i = tagRowsIndex + 2; i < TempTableRows.size(); i++) {
				XWPFTableRow newCreateRow = newCreateTable.createRow();
				CopyTableRow(newCreateRow, TempTableRows.get(i));// 複製行
				replaceTableRow(newCreateRow, parametersMap);// 處理不循環標籤的替換
			}
			newCreateTable.removeRow(0);// 移除多出來的第一行
			document.createParagraph();// 添加回車換行

		} else if (flag == 3) {
			//表格不循環僅簡單替換標籤
			List<XWPFTableRow> templateTableRows = templateTable.getRows();// 獲取模板表格全部行
			XWPFTable newCreateTable = document.createTable();// 建立新表格,默認一行一列
			for (int i = 0; i < templateTableRows.size(); i++) {
				XWPFTableRow newCreateRow = newCreateTable.createRow();
				CopyTableRow(newCreateRow, templateTableRows.get(i));// 複製模板行文本和樣式到新行
			}
			newCreateTable.removeRow(0);// 移除多出來的第一行
			document.createParagraph();// 添加回車換行
			replaceTable(newCreateTable, parametersMap);

		} else if (flag == 0) {
			List<XWPFTableRow> templateTableRows = templateTable.getRows();// 獲取模板表格全部行
			XWPFTable newCreateTable = document.createTable();// 建立新表格,默認一行一列
			for (int i = 0; i < templateTableRows.size(); i++) {
				XWPFTableRow newCreateRow = newCreateTable.createRow();
				CopyTableRow(newCreateRow, templateTableRows.get(i));// 複製模板行文本和樣式到新行
			}
			newCreateTable.removeRow(0);// 移除多出來的第一行
			document.createParagraph();// 添加回車換行
		}

	}






	/**
	 * 根據 模板段落 和 數據 在文檔末尾生成段落
	 *
	 * @author Juveniless
	 * @date 2017年11月27日 上午11:49:42
	 * @param templateParagraph
	 *            模板段落
	 * @param list
	 *            循環數據集
	 * @param parametersMap
	 *            不循環數據集
	 * @param flag
	 *            (0爲不循環替換,1爲循環替換)
	 *
	 */
	public void addParagraphInDocFooter(XWPFParagraph templateParagraph,
			List<Map<String, String>> list, Map<String, Object> parametersMap, int flag) {

		if (flag == 0) {
			XWPFParagraph createParagraph = document.createParagraph();
			// 設置段落樣式
			createParagraph.getCTP().setPPr(templateParagraph.getCTP().getPPr());
			// 移除原始內容
			for (int pos = 0; pos < createParagraph.getRuns().size(); pos++) {
				createParagraph.removeRun(pos);
			}
			// 添加Run標籤
			for (XWPFRun s : templateParagraph.getRuns()) {
				XWPFRun targetrun = createParagraph.createRun();
				CopyRun(targetrun, s);
			}

			replaceParagraph(createParagraph, parametersMap);

		} else if (flag == 1) {
			// 暫無實現
		}

	}




	/**
	 * 根據map替換段落元素內的{**}標籤
	 * @author Juveniless
	 * @date 2017年12月4日 下午3:09:00
	 * @param xWPFParagraph
	 * @param parametersMap
	 *
	 */
	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  ) {
					key.append(beginRunText.substring(beginIndex+1));
				}
				ArrayList<Integer> removeRunList = new ArrayList<>();//須要移除的run
				//處理中間的run
				for (int i = beginRunIndex + 1; i < endRunIndex; i++) {
					XWPFRun run = runs.get(i);
					String runText = run.text();
					key.append(runText);
					removeRunList.add(i);
				}

				// 獲取endRun中的key值
				XWPFRun endRun = runs.get(endRunIndex);
				String endRunText = endRun.text();
				int endIndex = endRunText.indexOf("}");
				//run中**}或者**}**
				if (endRunText.length()>1 && endIndex!=0) {
					key.append(endRunText.substring(0,endIndex));
				}



				//*******************************************************************
				//取得key值後替換標籤

				//先處理開始標籤
				if (beginRunText.length()==2 ) {
					// run標籤內文本{
					XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex);
					insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr());
					// 設置文本
					insertNewRun.setText(getValueBykey(key.toString(),parametersMap));
					xWPFParagraph.removeRun(beginRunIndex + 1);//移除原始的run
				}else {
					// 該run標籤爲**{**或者 {** ,替換key後,還須要加上原始key前的文本
					XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex);
					insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr());
					// 設置文本
					String textString=beginRunText.substring(0,beginRunText.indexOf("{"))+getValueBykey(key.toString(),parametersMap);
					insertNewRun.setText(textString);
					xWPFParagraph.removeRun(beginRunIndex + 1);//移除原始的run
				}

				//處理結束標籤
				if (endRunText.length()==1 ) {
					// run標籤內文本只有}
					XWPFRun insertNewRun = xWPFParagraph.insertNewRun(endRunIndex);
					insertNewRun.getCTR().setRPr(endRun.getCTR().getRPr());
					// 設置文本
					insertNewRun.setText("");
					xWPFParagraph.removeRun(endRunIndex + 1);//移除原始的run

				}else {
					// 該run標籤爲**}**或者 }** 或者**},替換key後,還須要加上原始key後的文本
					XWPFRun insertNewRun = xWPFParagraph.insertNewRun(endRunIndex);
					insertNewRun.getCTR().setRPr(endRun.getCTR().getRPr());
					// 設置文本
					String textString=endRunText.substring(endRunText.indexOf("}")+1);
					insertNewRun.setText(textString);
					xWPFParagraph.removeRun(endRunIndex + 1);//移除原始的run
				}

				//處理中間的run標籤
				for (int i = 0; i < removeRunList.size(); i++) {
					XWPFRun xWPFRun = runs.get(removeRunList.get(i));//原始run
					XWPFRun insertNewRun = xWPFParagraph.insertNewRun(removeRunList.get(i));
					insertNewRun.getCTR().setRPr(xWPFRun.getCTR().getRPr());
					insertNewRun.setText("");
					xWPFParagraph.removeRun(removeRunList.get(i) + 1);//移除原始的run
				}

			}// 處理${**}被分紅多個run

			replaceParagraph( xWPFParagraph, parametersMap);

		}//if 有標籤

	}








	/**
	 * 複製表格行XWPFTableRow格式
	 *
	 * @param target
	 *            待修改格式的XWPFTableRow
	 * @param source
	 *            模板XWPFTableRow
	 */
	private void CopyTableRow(XWPFTableRow target, XWPFTableRow source) {

		int tempRowCellsize = source.getTableCells().size();// 模板行的列數
		for (int i = 0; i < tempRowCellsize - 1; i++) {
			target.addNewTableCell();// 爲新添加的行添加與模板表格對應行行相同個數的單元格
		}
		// 複製樣式
		target.getCtRow().setTrPr(source.getCtRow().getTrPr());
		// 複製單元格
		for (int i = 0; i < target.getTableCells().size(); i++) {
			copyTableCell(target.getCell(i), source.getCell(i));
		}
	}





	/**
	 * 複製單元格XWPFTableCell格式
	 *
	 * @author Juveniless
	 * @date 2017年11月27日 下午3:41:02
	 * @param newTableCell
	 *            新建立的的單元格
	 * @param templateTableCell
	 *            模板單元格
	 *
	 */
	private void copyTableCell(XWPFTableCell newTableCell, XWPFTableCell templateTableCell) {
		// 列屬性
		newTableCell.getCTTc().setTcPr(templateTableCell.getCTTc().getTcPr());
		// 刪除目標 targetCell 全部文本段落
		for (int pos = 0; pos < newTableCell.getParagraphs().size(); pos++) {
			newTableCell.removeParagraph(pos);
		}
		// 添加新文本段落
		for (XWPFParagraph sp : templateTableCell.getParagraphs()) {
			XWPFParagraph targetP = newTableCell.addParagraph();
			copyParagraph(targetP, sp);
		}
	}

	/**
	 * 複製文本段落XWPFParagraph格式
	 *
	 * @author Juveniless
	 * @date 2017年11月27日 下午3:43:08
	 * @param newParagraph
	 *            新建立的的段落
	 * @param templateParagraph
	 *            模板段落
	 *
	 */
	private void copyParagraph(XWPFParagraph newParagraph, XWPFParagraph templateParagraph) {
		// 設置段落樣式
		newParagraph.getCTP().setPPr(templateParagraph.getCTP().getPPr());
		// 添加Run標籤
		for (int pos = 0; pos < newParagraph.getRuns().size(); pos++) {
			newParagraph.removeRun(pos);

		}
		for (XWPFRun s : templateParagraph.getRuns()) {
			XWPFRun targetrun = newParagraph.createRun();
			CopyRun(targetrun, s);
		}

	}

	/**
	 * 複製文本節點run
	 * @author Juveniless
	 * @date 2017年11月27日 下午3:47:17
	 * @param newRun
	 *            新建立的的文本節點
	 * @param templateRun
	 *            模板文本節點
	 *
	 */
	private void CopyRun(XWPFRun newRun, XWPFRun templateRun) {
		newRun.getCTR().setRPr(templateRun.getCTR().getRPr());
		// 設置文本
		newRun.setText(templateRun.text());


	}




	/**
	 * 根據參數parametersMap對錶格的一行進行標籤的替換
	 *
	 * @author Juveniless
	 * @date 2017年11月23日 下午2:09:24
	 * @param tableRow
	 *            表格行
	 * @param parametersMap
	 *            參數map
	 *
	 */
	public void replaceTableRow(XWPFTableRow tableRow, Map<String, Object> parametersMap) {

		List<XWPFTableCell> tableCells = tableRow.getTableCells();
		for (XWPFTableCell xWPFTableCell : tableCells) {
			List<XWPFParagraph> paragraphs = xWPFTableCell.getParagraphs();
			for (XWPFParagraph xwpfParagraph : paragraphs) {

				replaceParagraph(xwpfParagraph, parametersMap);
			}
		}

	}





	/**
	 * 根據map替換表格中的{key}標籤
	 * @author Juveniless
	 * @date 2017年12月4日 下午2:47:36
	 * @param xwpfTable
	 * @param parametersMap
	 *
	 */
	public void replaceTable(XWPFTable xwpfTable,Map<String, Object> parametersMap){
		List<XWPFTableRow> rows = xwpfTable.getRows();
		for (XWPFTableRow xWPFTableRow : rows ) {
			List<XWPFTableCell> tableCells = xWPFTableRow.getTableCells();
			for (XWPFTableCell xWPFTableCell : tableCells ) {
				List<XWPFParagraph> paragraphs2 = xWPFTableCell.getParagraphs();
				for (XWPFParagraph xWPFParagraph : paragraphs2) {
					replaceParagraph(xWPFParagraph, parametersMap);
				}
			}
		}

	}



	private String getValueBykey(String key, Map<String, Object> map) {
		String returnValue="";
		if (key != null) {
			try {
				returnValue=map.get(key)!=null ? map.get(key).toString() : "";
			} catch (Exception e) {
				// TODO: handle exception
				System.out.println("key:"+key+"***"+e);
				returnValue="";
			}

		}
		return returnValue;
	}








}
  • **使用 **

package com.hidata.tool;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {

	public static void main(String[] args) throws IOException {

		Map<String, Object> wordDataMap = new HashMap<String, Object>();// 存儲報表所有數據
		Map<String, Object> parametersMap = new HashMap<String, Object>();// 存儲報表中不循環的數據



		List<Map<String, Object>> table1 = new ArrayList<Map<String, Object>>();
		Map<String, Object> map1=new HashMap<>();
		map1.put("name", "張三");
		map1.put("age", "23");
		map1.put("email", "12121@qq.com");

		Map<String, Object> map2=new HashMap<>();
		map2.put("name", "李四");
		map2.put("age", "45");
		map2.put("email", "45445@qq.com");

		Map<String, Object> map3=new HashMap<>();
		map3.put("name", "Tom");
		map3.put("age", "34");
		map3.put("email", "6767@qq.com");

		table1.add(map1);
		table1.add(map2);
		table1.add(map3);




		List<Map<String, Object>> table2 = new ArrayList<Map<String, Object>>();
		Map<String, Object> map4=new HashMap<>();
		map4.put("name", "tom");
		map4.put("number", "sd1234");
		map4.put("address", "上海");

		Map<String, Object> map5=new HashMap<>();
		map5.put("name", "seven");
		map5.put("number", "sd15678");
		map5.put("address", "北京");

		Map<String, Object> map6=new HashMap<>();
		map6.put("name", "lisa");
		map6.put("number", "sd9078");
		map6.put("address", "廣州");

		table2.add(map4);
		table2.add(map5);
		table2.add(map6);



		parametersMap.put("userName", "JUVENILESS");
		parametersMap.put("time", "2018-03-24");
		parametersMap.put("sum", "3");


		wordDataMap.put("table1", table1);
		wordDataMap.put("table2", table2);
		wordDataMap.put("parametersMap", parametersMap);
		File file = new File("D:\\Workspaces\\Eclipse 2017\\wordTemplate\\doc\\模板.docx");//改爲你本地文件所在目錄


		// 讀取word模板
		FileInputStream fileInputStream = new FileInputStream(file);
		WordTemplate template = new WordTemplate(fileInputStream);

		// 替換數據
		template.replaceDocument(wordDataMap);


		//生成文件
		File outputFile=new File("D:\\Workspaces\\Eclipse 2017\\wordTemplate\\doc\\輸出.docx");//改爲你本地文件所在目錄
		FileOutputStream fos  = new FileOutputStream(outputFile);
		template.getDocument().write(fos);

	}

}
相關文章
相關標籤/搜索