【无标题】

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

}

相关推荐
TracyCoder12321 小时前
Maven 依赖管理核心配置模板及最佳实践
java·maven
Chase_______21 小时前
【Maven篇】我整理了一篇Maven笔记
笔记·python·maven
q***46421 小时前
maven导入spring框架
数据库·spring·maven
e***282921 小时前
(CICD)自动化构建打包、部署(Jenkins + maven+ gitlab+tomcat)
自动化·jenkins·maven
天庭鸡腿哥2 天前
谷歌出品,堪称手机版PS!
javascript·智能手机·eclipse·maven
q***12532 天前
Plugin ‘org.springframework.bootspring-boot-maven-plugin‘ not found(已解决)
java·前端·maven
东东__net2 天前
java项目管理工具Maven
java·maven
踏浪无痕2 天前
Maven父子模块Deploy的那些坑
后端·maven
王者之座2 天前
java+maven配置yguard的一次实验
java·spring boot·maven