【无标题】

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");           // 黑色
}

}

相关推荐
晓13138 小时前
后端篇——第一章 Maven基础全面教程
java·maven
wa的一声哭了9 小时前
内积空间 内积空间二
java·开发语言·python·spring·java-ee·django·maven
晓13139 小时前
后端篇——第二章 Maven高级全面教程
java·maven
中年程序员一枚1 天前
Springboot使用maven编译报juh-3.2.1.jar缺失
spring boot·maven·jar
哆la不懂a梦1 天前
测试1233211
maven
小肖爱笑不爱笑1 天前
Maven
java·log4j·maven
FreeBuf_1 天前
攻击者伪造Jackson JSON库入侵Maven中央仓库
java·json·maven
飞舞花下2 天前
MAVEN私有仓库配置-Nexus私有仓库
xml·java·maven
while(1){yan}2 天前
使用HuTool实现验证码
spring boot·spring·java-ee·maven
PWRJOY2 天前
解决Flutter构建安卓项目卡在Flutter: Running Gradle task ‘assembleDebug‘...:替换国内 Maven 镜像
android·flutter·maven