Java 使用 poi 获取不到 docx 中表格的书签问题

目录

问题

如何解决

代码

替换书签方法

测试


问题

实际项目中遇到个需求,需要替换 docx 中书签的内容。

使用 poi 读取 docx 的书签,直接获取文档中的段落(paragraph)的书签然后进行替换内容,处理完后发现文档中表格里的书签并没有被替换

如何解决

文档中每个单元格里的内容也是段落(paragraph),将表格中的书签做单独处理,先获取所有表格(table)所有单元格(cell),再获取段落进行书签替换即可

代码

替换书签方法

public class WordUtil {

    /**
     * 处理表格中的书签 每个单元格里的内容都可以看作一个段落
     * 
     * @param xwpfDocument 文档对象
     * @param dataMap 书签内容
     */
    public static void dealBookmarkOfDocx(XWPFDocument xwpfDocument, Map<String, String> dataMap) throws IOException {
        //处理表格中的书签
        List<XWPFTable> tableList = xwpfDocument.getTables();
        for (XWPFTable table : tableList) {
            int rowCount = table.getNumberOfRows();//获取table的行数
            for (int i = 0; i < rowCount; i++) {
                XWPFTableRow row = table.getRow(i);
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    dealParagraphBookmark(cell.getParagraphs(), dataMap);
                }
            }
        }
        //处理段落里的书签
        List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs();
        dealParagraphBookmark(paragraphs, dataMap);
    }

    /**
     * 替换每个段落中的书签
     *
     * @param paragraphList 段落list
     * @param dataMap 书签内容
     */
    private static void dealParagraphBookmark(List<XWPFParagraph> paragraphList, Map<String, String> dataMap) {
        for (XWPFParagraph paragraph : paragraphList) {
            CTP ctp = paragraph.getCTP();
            for (int i = 0; i < ctp.sizeOfBookmarkEndArray(); i++) {
                CTBookmark bookmark = ctp.getBookmarkStartArray(i);
                String bookmarkName = bookmark.getName();
                if (dataMap.containsKey(bookmarkName)) {
                    XWPFRun xwpfRun = paragraph.createRun();
                    xwpfRun.setText(dataMap.get(bookmarkName));

                    Node firstNode = bookmark.getDomNode();
                    Node nextNode = firstNode.getNextSibling();
                    while (nextNode != null) {
                        String nodeName = nextNode.getNodeName();
                        if (nodeName.equalsIgnoreCase("w:bookmarkEnd")) {
                            break;
                        }
                        Node delNode = nextNode;
                        nextNode = nextNode.getNextSibling();
                        ctp.getDomNode().removeChild(delNode);
                    }
                    if (nextNode == null) {
                        //找不到结束标识,在书签前面加
                        ctp.getDomNode().insertBefore(xwpfRun.getCTR().getDomNode(), firstNode);
                    } else {
                        //找到结束符,将新内容添加到结束符之前,即内容写入bookmark中间
                        ctp.getDomNode().insertBefore(xwpfRun.getCTR().getDomNode(), nextNode);
                    }
                }
            }
        }
    }
}

测试

class WordUtilTest {

    @Test
    void dealBookmarkOfDocx() {
        String docxPath = "C:\\Users\\XXX\\Desktop\\myDoc.docx";

        Map<String, String> dataMap = new HashMap<>();
        dataMap.put("bookmark1", "1234567");

        try (InputStream inputStream = Files.newInputStream(Paths.get(docxPath));
             XWPFDocument xDoc = new XWPFDocument(inputStream)) {

            WordUtil.dealBookmarkOfDocx(xDoc, dataMap);

            xDoc.write(Files.newOutputStream(Paths.get(docxPath)));

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要使用POI获取Word文档表格的数据,可以按照以下步骤进行: 1. 首先,使用POI库打开Word文档。例如,使用XWPFDocument类打开.docx文件。 ```java FileInputStream fis = new FileInputStream("example.docx"); XWPFDocument doc = new XWPFDocument(fis); ``` 2. 然后,使用getTables()方法获取文档的所有表格,该方法返回一个XWPFTable的List。 ```java List<XWPFTable> tables = doc.getTables(); ``` 3. 对于每个表格使用getRows()方法获取表格的所有行,该方法返回一个XWPFTableRow的List。 ```java for(XWPFTable table : tables) { List<XWPFTableRow> rows = table.getRows(); for(XWPFTableRow row : rows) { // 处理行数据 } } ``` 4. 对于每一行,使用getTableCells()方法获取该行的所有单元格,该方法返回一个XWPFTableCell的List。 ```java for(XWPFTable table : tables) { List<XWPFTableRow> rows = table.getRows(); for(XWPFTableRow row : rows) { List<XWPFTableCell> cells = row.getTableCells(); for(XWPFTableCell cell : cells) { // 处理单元格数据 } } } ``` 5. 对于每个单元格,使用getText()方法获取单元格的文本内容。 ```java for(XWPFTable table : tables) { List<XWPFTableRow> rows = table.getRows(); for(XWPFTableRow row : rows) { List<XWPFTableCell> cells = row.getTableCells(); for(XWPFTableCell cell : cells) { String text = cell.getText(); // 处理单元格的文本内容 } } } ``` 这样就可以获取Word文档所有表格的所有行和单元格的数据了。 ### 回答2: 使用Java利用POI获取Word文档表格的数据,可以通过以下步骤实现: 1. 导入POI库:首先需要在Java项目导入POI库,并将库文件添加到项目的classpath。 2. 加载Word文档:使用POI的XWPFDocument类加载Word文档,代码如下: ```java InputStream in = new FileInputStream("path/to/word/document.docx"); XWPFDocument doc = new XWPFDocument(in); ``` 3. 获取所有表格:通过getTables()方法获取Word文档的所有表格,代码如下: ```java List<XWPFTable> tables = doc.getTables(); ``` 4. 遍历表格:可以使用循环遍历所有表格,根据需要进行操作,例如获取表格的数据等。 ```java for (XWPFTable table : tables) { // 获取表格的行 List<XWPFTableRow> rows = table.getRows(); // 遍历行 for (XWPFTableRow row : rows) { // 获取行的单元格 List<XWPFTableCell> cells = row.getTableCells(); // 遍历单元格 for (XWPFTableCell cell : cells) { // 获取单元格的内容 String content = cell.getText(); // 处理单元格数据,例如打印或保存到其他地方 System.out.println(content); } } } ``` 通过以上步骤,可以使用Java利用POI获取Word文档表格的数据。根据实际需求,可以对获取到的数据进行处理,例如保存到数据库或生成其他格式的文档。 ### 回答3: Java利用POI可以很方便地获取Word文档表格的数据。下面是实现的步骤: 1. 导入POI库:首先需要在Java工程导入POI的相关库文件,可以使用Maven或手动下载并导入。 2. 创建Word文档对象:使用XWPFDocument类创建一个Word文档对象,打开需要解析的Word文档。 3. 获取文档表格使用getTables()方法获取文档所有的表格,返回一个List对象。 4. 遍历表格使用for循环遍历表格列表,可以通过getTable()方法获取每个表格。 5. 获取表格的行并遍历:使用getRows()方法获取表格所有的行,返回一个List对象。然后使用for循环遍历行列表,可以通过getRow()方法获取每一行。 6. 获取的单元格并遍历:使用getTableCells()方法获取所有的单元格,返回一个List对象。然后使用for循环遍历单元格列表,可以通过getTableCell()方法获取每个单元格。 7. 获取单元格的文本:使用getText()方法获取单元格的文本内容。 完整的示例代码如下: ```java import org.apache.poi.xwpf.usermodel.*; import java.io.FileInputStream; import java.io.IOException; import java.util.List; public class ReadTableData { public static void main(String[] args) { try { // 创建Word文档对象 XWPFDocument document = new XWPFDocument(new FileInputStream("example.docx")); // 获取文档的所有表格 List<XWPFTable> tables = document.getTables(); // 遍历表格 for (XWPFTable table : tables) { // 获取表格的所有行 List<XWPFTableRow> rows = table.getRows(); // 遍历行 for (XWPFTableRow row : rows) { // 获取的所有单元格 List<XWPFTableCell> cells = row.getTableCells(); // 遍历单元格 for (XWPFTableCell cell : cells) { // 获取单元格的文本内容 String text = cell.getText(); System.out.println(text); } } } // 关闭文档 document.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` 以上就是使用POI获取Word文档表格数据的基本步骤和示例代码。通过POI的各种API可以更加灵活地处理表格的数据,比如可以合并、拆分单元格,修改样式等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值