【无标题】

import org.apache.poi.xwpf.usermodel.;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.
;

import java.math.BigInteger;

import java.util.List;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

public class WordExportUtil {

复制代码
/**
 * 替换 Word 文档中的占位符
 *
 * @param document    Word文档对象
 * @param placeholder 占位符名称 (例如 "{unitName}")
 * @param value       占位符对应的值
 */
public static void replacePlaceholder(XWPFDocument document, String placeholder, String value) {
	if (document == null || placeholder == null || value == null) {
		return;
	}
	String regex = Pattern.quote(placeholder);
	Pattern pattern = Pattern.compile(regex);
	for (XWPFParagraph paragraph : document.getParagraphs()) {
		Matcher matcher = pattern.matcher(paragraph.getText());
		if (matcher.find()) {
			// 为了安全起见,我们不直接修改paragraph的text,而是替换其run
			for (XWPFRun run : paragraph.getRuns()) {
				if (run.getText(0) != null && run.getText(0).contains(placeholder)) {
					run.setText(run.getText(0).replace(placeholder, value), 0);
				}
			}
		}
	}

	// 同时检查表格中的内容
	for (XWPFTable table : document.getTables()) {
		for (XWPFTableRow row : table.getRows()) {
			for (XWPFTableCell cell : row.getTableCells()) {
				for (XWPFParagraph para : cell.getParagraphs()) {
					for (XWPFRun run : para.getRuns()) {
						if (run.getText(0) != null && run.getText(0).contains(placeholder)) {
							run.setText(run.getText(0).replace(placeholder, value), 0);
						}
					}
				}
			}
		}
	}
}


/**
 * 填充在线注册申请表中的账号信息表格
 * 此方法会查找包含 "账号信息" 的单元格,并在该单元格内插入一个完整的表格。
 * 该表格包含表头:"姓名", "手机号", "账号", "账号说明"
 * 并根据 accountInfos 列表填充数据行。
 *
 * @param document     Word文档对象
 * @param accountInfos 账号信息列表
 */
public static void fillAccountTableForOnlineRegistration(XWPFDocument document, List<InternetAccountInfo> accountInfos) {
	if (document == null || accountInfos == null || accountInfos.isEmpty()) {
		return; // 如果文档或数据为空,则无需处理
	}

	// 遍历文档中的所有表格
	for (XWPFTable table : document.getTables()) {
		// 遍历表格中的每一行
		for (XWPFTableRow row : table.getRows()) {
			// 遍历该行中的每一个单元格
			for (XWPFTableCell cell : row.getTableCells()) {
				// 查找包含 "账号信息" 的单元格
				if (cell.getText().contains("{applicationRows}")) {
					// 找到了目标单元格,现在需要在其内部插入表格
					insertAccountTableIntoCell(cell, accountInfos, document);
					return; // 找到并处理完后退出循环
				}
			}
		}
	}
}

private static void insertAccountTableIntoCell(XWPFTableCell targetCell, List<InternetAccountInfo> accountInfos, XWPFDocument document) {
	try {
		// 1. 清空目标单元格内容
		while (targetCell.getParagraphs().size() > 0) {
			targetCell.removeParagraph(0);
		}

		// 2. 获取单元格对应的底层 CTTc 对象
		CTTc ctTc = targetCell.getCTTc();

		// 3. 创建一个新的表格 (CTTbl)
		CTTbl ctTbl = ctTc.addNewTbl();

		// 4. 设置表格网格(列宽可选,这里简单均分)
		CTTblGrid tblGrid = ctTbl.addNewTblGrid();
		int colCount = 4;
		int totalWidth = 5000; // 总宽度(单位: twentieth-millimeter, 可调整)
		int colWidth = totalWidth / colCount;
		for (int i = 0; i < colCount; i++) {
			CTTblGridCol gridCol = tblGrid.addNewGridCol();
			gridCol.setW(BigInteger.valueOf(colWidth));
		}

		// 5. 添加表头行
		CTRow headerRow = ctTbl.addNewTr();
		String[] headers = {"姓名", "手机号", "账号", "账号说明"};
		for (String header : headers) {
			CTTc cell = headerRow.addNewTc();
			cell.addNewP().addNewR().addNewT().setStringValue(header);
			// 可选:设置边框或样式
		}

		// 6. 添加数据行
		for (InternetAccountInfo info : accountInfos) {
			CTRow dataRow = ctTbl.addNewTr();
			addCell(dataRow, info.getName());
			addCell(dataRow, info.getPhone());
			addCell(dataRow, info.getAccount());
			addCell(dataRow, info.getDescription());
		}

		// 7. (可选)设置表格边框
		setTableBorders(ctTbl);

	} catch (Exception e) {
		e.printStackTrace();
	}
}

// 辅助方法:向 CTRow 添加一个带文本的单元格
private static void addCell(CTRow row, String text) {
	CTTc cell = row.addNewTc();
	CTP p = cell.addNewP();
	CTR r = p.addNewR();
	CTText t = r.addNewT();
	t.setStringValue(text != null ? text : "");
}

// 辅助方法:为 CTTbl 设置边框(单线、黑色)
private static void setTableBorders(CTTbl table) {
	CTTblPr tblPr = table.getTblPr();
	if (tblPr == null) {
		tblPr = table.addNewTblPr();
	}

	CTTblBorders borders = tblPr.getTblBorders();
	if (borders == null) {
		borders = tblPr.addNewTblBorders();
	}

	setBorder(borders.addNewTop());
	setBorder(borders.addNewBottom());
	setBorder(borders.addNewLeft());
	setBorder(borders.addNewRight());
	setBorder(borders.addNewInsideH());
	setBorder(borders.addNewInsideV());
}

private static void setBorder(CTBorder border) {
	border.setVal(STBorder.SINGLE);
	border.setSz(BigInteger.valueOf(4)); // 线宽
	border.setColor("000000");           // 黑色
}

}

相关推荐
Spider Cat 蜘蛛猫2 天前
`mapper-locations` 和 `@MapperScan`区别
java·spring·maven
程序员阿鹏2 天前
tomcat正常启动但 SpringMVC 控制器无法启动
java·spring·servlet·tomcat·maven·intellij-idea
TT哇2 天前
【项目】玄策五子——匹配模块
java·spring boot·websocket·spring·java-ee·maven
醇氧2 天前
没有Maven私服引入本地jar文件
java·maven·jar
基哥的奋斗历程2 天前
Maven私有仓库搭建与配置指南
java·maven
浪潮IT馆3 天前
win11安装maven
java·maven
计算机毕设指导63 天前
基于微信小程序的电子数据取证知识测试系统【源码文末联系】
java·spring boot·微信小程序·小程序·tomcat·maven·intellij idea
2201_757830873 天前
Maven
java·maven
invicinble3 天前
idea提供maven处理机制
java·maven·intellij-idea
真上帝的左手3 天前
3. 代码管理-构建工具-Maven
java·maven