package com.example.demo; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.data.*; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.xwpf.usermodel.*; import org.apache.xmlbeans.XmlCursor; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.nodes.Node; import org.jsoup.select.Elements; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; public class InsertAtPositionExample { public static void main(String[] args) throws IOException, InvalidFormatException { // 模拟获取前端传输过来的base64 String text = new String(Files.readAllBytes(Paths.get(GetWebProjectRealPathTool.getRootPath() + "/abc.txt")), StandardCharsets.UTF_8); Document orignDocument = Jsoup.parseBodyFragment(text); Documents.DocumentBuilder of = Documents.of(); Elements links = orignDocument.getElementsByTag("p"); Elements allElements = orignDocument.body().children(); // 遍历插入到临时的段落里 for (Element element : allElements) { if (element.tagName().equals("p")) { for (Node child : element.childNodes()) { if (child.nodeName().equals("img")) { // 这是一个标签,处理图片 String src = child.attr("src"); if (src.contains("base64,")) { of.addParagraph(Paragraphs.of(Pictures.ofBase64(src, PictureType.PNG).create()).create()); } } else if (child.nodeName().equals("#text")) { // 这是一个文本节点,处理文本 String t = child.toString().trim(); if (!t.isEmpty()) { of.addParagraph(Paragraphs.of(t.replace(" ", " ")).create()); } } } } else if (element.tagName().equals("table")) { // 新代码:处理表格 TableRenderData tableData = parseTable(element); of.addTable(tableData); } } // 初始数据create DocumentRenderData data = of.create(); XWPFTemplate orignTemplate = XWPFTemplate.create(data); // ----定位后插入 // 加载模板 XWPFTemplate template = XWPFTemplate.compile(GetWebProjectRealPathTool.getRootPath() + "/ccmuJsfw.docx"); XWPFDocument document = template.getXWPFDocument(); // 定位到特定位置,例如在"审计抽查)"后面插入段落 List paragraphs = document.getParagraphs(); XWPFParagraph targetPara = null; for (XWPFParagraph paragraph : paragraphs) { if (paragraph.getText().contains("审计抽查)")) { targetPara = paragraph; break; } } XmlCursor cursor = targetPara.getCTP().newCursor(); List iBodyElements = orignTemplate.getXWPFDocument().getBodyElements(); for (IBodyElement e : iBodyElements) { if (e.getElementType().toString().equals("PARAGRAPH")) { XWPFParagraph paragraph = (XWPFParagraph) e; cursor.toEndToken(); // 移动到当前段落的末尾 cursor.toNextToken(); // 移动到下一个元素 XWPFParagraph newParagraph = document.insertNewParagraph(cursor); List runs = paragraph.getRuns(); for (XWPFRun r : runs) { if ("".equals(r.text()) && r.getEmbeddedPictures().size() == 0) { continue; } XWPFRun run = newParagraph.createRun(); // 设置字体大小(以半点为单位,所以 28 对应 14pt) run.setFontSize(12); run.setBold(true); run.setFontFamily("宋体"); run.setText(r.text()); // 在当前位置创建新段落 if (r.getEmbeddedPictures() != null) { for (XWPFPicture pic : r.getEmbeddedPictures()) { InputStream picStream = pic.getPictureData().getPackagePart().getInputStream(); int format = pic.getPictureData().getPictureType(); // 从源Run获取图片的宽度和高度 long width = pic.getCTPicture().getSpPr().getXfrm().getExt().getCx(); long height = pic.getCTPicture().getSpPr().getXfrm().getExt().getCy(); run = newParagraph.createRun(); // 将图片复制到目标Run run.addPicture(picStream, format, "image" + pic.getPictureData().getFileName(), (int) width, (int) height); } } } } else if (e.getElementType().toString().equals("TABLE")) { XWPFTable table = (XWPFTable) e; cursor.toEndToken(); // 移动到当前段落的末尾 cursor.toNextToken(); // 移动到下一个元素 XWPFTable newXWPFTable = document.insertNewTbl(cursor); newXWPFTable.removeRow(0); System.out.println(">>>>>>>>>>>"); System.out.println(table.getRows().size()); System.out.println(table.getRows().get(0).getTableCells().size()); // 遍历旧表格 for (int i = 0;i< table.getRows().size();i++) { XWPFTableRow srcTableRow = table.getRows().get(i); // 创建新行 // XWPFTableRow newRow = newXWPFTable.createRow(); newXWPFTable.addRow(srcTableRow, i); // 你可能需要调整行高,字体等行级属性 // newRow.setHeight(srcTableRow.getHeight()); // // 遍历所有单元格 // for (int j = 0; j < srcTableRow.getTableCells().size(); j++) { // // 获取旧单元格的数据 // String t = srcTableRow.getCell(j).getText(); // // // 创建新单元格并添加数据 // newRow.createCell().setText(t); // } } System.out.println(">>>>>>>>>>>"); System.out.println(newXWPFTable.getRows().size()); System.out.println(newXWPFTable.getRows().get(0).getTableCells().size()); } } // 保存修改后的文档 try { template.writeToFile(GetWebProjectRealPathTool.getRootPath() + "/path_to_output.docx"); } catch (IOException e) { e.printStackTrace(); } finally { if (template != null) { try { template.close(); } catch (IOException e) { e.printStackTrace(); } } } } private static TableRenderData parseTable(Element table) { Elements rows = table.select("tr"); int rowCount = rows.size(); int colCount = rows.get(0).select("th, td").size(); String[][] cellTexts = new String[rowCount][colCount]; for (int r = 0; r < rowCount; r++) { Elements cells = rows.get(r).select("th, td"); for (int c = 0; c < cells.size(); c++) { cellTexts[r][c] = cells.get(c).text(); } } return Tables.of(cellTexts).create(); } }