poi操作word模板(word2003,word2007)

近期老师给了个任务,要通过Word模版生成各类文档,主要就是将类似%title%,%name%,%content%等标签,通过类的方法,查询数据库并替换标签,上网查了一下,发现POI对文档操作比较不错,Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。Word2003的方法比较简单,大致通过Range替换文本,Word2007比较复杂点,遍历替换文本,参考了网上的案例,写了个demo,直接上代码。


package com.poi.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
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;
import com.poi.model.Person;

public class WordUtil {
	private Map<String, String> map = new HashMap<String, String>();//存放标签与替换的值
	private String templatePath;//模版路径

	public WordUtil(String templatePath,Person person) {
		this.templatePath = templatePath;
		if (templatePath.endsWith("docx")) {
			try {
				@SuppressWarnings("resource")
				XWPFWordExtractor docx = new XWPFWordExtractor(
						POIXMLDocument.openPackage(templatePath));
				String docxText = docx.getText();
				getValueMap(docxText,person);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			try {
				@SuppressWarnings("resource")
				WordExtractor doc = new WordExtractor(new FileInputStream(
						templatePath));
				String docText = doc.getText();
				getValueMap(docText,person);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	//遍历获取标签与通过对象替代的值
	private void getValueMap(String text,Person person) {
		Pattern pattern = Pattern.compile("%(.*?)%");
		Matcher matcher = pattern.matcher(text);
		while (matcher.find()) {
			String key = matcher.group(1);
			String value = person.getString(key);
			if (value == null) {
				value = "";
			}
			map.put(key, value);
		}
	}
	public void createDoc(String newPath) {
		if (templatePath.endsWith("docx")) {
			replaceDoc2007(newPath);
		} else {
			replaceDoc2003(newPath);
		}
	}

	public void replaceDoc2007(String newPath) {
		try {
			OPCPackage pack = POIXMLDocument.openPackage(templatePath);
			XWPFDocument doc = new XWPFDocument(pack);
			// 处理段落
			List<XWPFParagraph> paragraphList = doc.getParagraphs();
			processParagraphs(paragraphList, map);
			// 处理表格
			Iterator<XWPFTable> it = doc.getTablesIterator();
			while (it.hasNext()) {
				XWPFTable table = it.next();
				List<XWPFTableRow> rows = table.getRows();
				for (XWPFTableRow row : rows) {
					List<XWPFTableCell> cells = row.getTableCells();
					for (XWPFTableCell cell : cells) {
						List<XWPFParagraph> paragraphListTable = cell
								.getParagraphs();
						processParagraphs(paragraphListTable, map);
					}
				}
			}
			FileOutputStream fos = new FileOutputStream(newPath);
			doc.write(fos);
			fos.flush();
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void replaceDoc2003(String newPath) {
		String[] str = newPath.split(".doc");
		newPath = str[0] + ".doc";
		try {
			FileInputStream fis = new FileInputStream(new File(templatePath));
			HWPFDocument doc = new HWPFDocument(fis);
			Range bodyRange = doc.getRange();
			for (Map.Entry<String, String> entry : map.entrySet()) {
				bodyRange.replaceText("%" + entry.getKey() + "%",
						entry.getValue());
			}
			// 输出word文件
			ByteArrayOutputStream ostream = new ByteArrayOutputStream();
			doc.write(ostream);
			OutputStream outs = new FileOutputStream(newPath);
			outs.write(ostream.toByteArray());
			outs.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void processParagraphs(List<XWPFParagraph> paragraphList,
			Map<String, String> map) {
		for (XWPFParagraph paragraph : paragraphList) {
			List<XWPFRun> runs = paragraph.getRuns();
			for (XWPFRun run : runs) {
				String text = run.getText(0);
				boolean isSetText = false;
				for (Map.Entry<String, String> entry : map.entrySet()) {
					String key = entry.getKey();
					if (text.indexOf(key) != -1) {
						isSetText = true;
						text = text.replace("%" + entry.getKey() + "%",entry.getValue());
					}
				}
				if (isSetText) {
					run.setText(text, 0);
				}
			}
		}
	}


}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要使用 Apache POI 操作 Word 模板替换内容,你可以使用以下步骤: 1. 首先,你需要创建一个空白 Word 文档,并将其保存为模板文件(.dotx 或 .dotm)。 2. 使用 Apache POI 创建 Word 文档对象,使用模板文件作为输入。 ```java // 创建 Word 文档对象 XWPFDocument document = new XWPFDocument(new FileInputStream("template.dotx")); ``` 3. 获取文档中的所有段落和表格,并遍历它们以查找要替换的文本。 ```java // 获取文档中的所有段落和表格 List<IBodyElement> elements = document.getBodyElements(); for (IBodyElement element : elements) { if (element instanceof XWPFParagraph) { // 处理段落 XWPFParagraph paragraph = (XWPFParagraph) element; List<XWPFRun> runs = paragraph.getRuns(); for (XWPFRun run : runs) { String text = run.getText(0); if (text != null && text.contains("要替换的文本")) { // 替换文本 text = text.replace("要替换的文本", "替换后的文本"); run.setText(text, 0); } } } else if (element instanceof XWPFTable) { // 处理表格 XWPFTable table = (XWPFTable) element; List<XWPFTableRow> rows = table.getRows(); for (XWPFTableRow row : rows) { List<XWPFTableCell> cells = row.getTableCells(); for (XWPFTableCell cell : cells) { List<XWPFParagraph> paragraphs = cell.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { List<XWPFRun> runs = paragraph.getRuns(); for (XWPFRun run : runs) { String text = run.getText(0); if (text != null && text.contains("要替换的文本")) { // 替换文本 text = text.replace("要替换的文本", "替换后的文本"); run.setText(text, 0); } } } } } } } ``` 4. 使用 Apache POI 将修改后的 Word 文档保存到文件中。 ```java // 保存 Word 文档 FileOutputStream out = new FileOutputStream("output.docx"); document.write(out); out.close(); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值