为有中文需求的客户提供多渠道中文技术支持.

Tue Aug 02, 2022 6:52 am

各位老师好!

我的word文档里面有多个表格,表格里的书签跨多行多列,我试图获取该书签中的内容,并进行替换,具体代码如下,但是无法成功,不知道该如何修改代码?

Code: Select all
import com.spire.doc.*;
import com.spire.doc.documents.*;
import com.spire.doc.fields.TextRange;

public class Main {

    public static void main(String[] args) {
        //加载word文档
        Document doc = new Document("XXXXX.dot");
        BookmarksNavigator bookmarkNavigator = new BookmarksNavigator(doc);

        //获取书签内容
        bookmarkNavigator.moveToBookmark("tblA3QJ00_F");
        TextBodyPart textBodyPart = bookmarkNavigator.getBookmarkContent();

        String text = "";

        for(Object item: textBodyPart.getBodyItems()){
            if(item instanceof Paragraph){
                Paragraph paragraph = (Paragraph) item;

                for (Object childObj: paragraph.getChildObjects()){
                    if (childObj instanceof TextRange){
                        TextRange textRange = (TextRange) childObj;
                        text = text + textRange.getText();
                    }
                }
            }
        }

        System.out.println(text);
    }
}


报错:
itemStart and itemEnd must be contained in one text body at com.spire.doc.documents.TextBodySelection.<init>(Unknown Source)...

Wang_Student
 
Posts: 5
Joined: Tue Aug 02, 2022 6:07 am

Tue Aug 02, 2022 7:49 am

您好,

感谢您的咨询。

首先,您不能将书签的开始和结束标记放置于不同的作用域内。例如此场景中的不同单元格中。
bookmarkNavigator.getBookmarkContent()方法是获取当前书签的开始与结束标记之间的内容并将它们放置到一个单独的作用域对象内并返回。但类似您这样的场景就会出现问题。单元格是没办法脱离表格本身而存在的,它并不能单独作为作用域内的一个子对象(表格才可以)。再比如您将一个书签的开始标记放置在一个表格内部,而结束标记放置在表格外部,那么对于bookmarkNavigator.getBookmarkContent()方法来说,需要返回的内容就很矛盾了。返回内容中是直接包含整个表格呢还是说以一种复杂的形式返回单个单元格呢?这都不合理。
因此,对于您的需求。我想到两种方案给您参考。希望它能帮到您。
1. 在每个目标单元格内单独设置书签(一个单元格内就可以看做一个单独的作用域了,保证书签开始和结束标签在同一个作用域那就可以),而后依次通过书签名定位到对应的单元格并替换内容。
2. 直接获取Table对象,按目标单元格所在的行列坐标来获取单元格对象,并修改其中的内容。
Sincerely,
Andy
E-iceblue support team
User avatar

Andy.Zhou
 
Posts: 483
Joined: Mon Mar 29, 2021 3:03 am

Wed Aug 03, 2022 5:32 am

您好!

非常详细的解答,非常感谢!!

Wang_Student
 
Posts: 5
Joined: Tue Aug 02, 2022 6:07 am

Wed Aug 03, 2022 8:58 am

不客气。有问题再联系 :D
Sincerely,
Andy
E-iceblue support team
User avatar

Andy.Zhou
 
Posts: 483
Joined: Mon Mar 29, 2021 3:03 am

Thu Feb 16, 2023 11:59 am

您好!我又遇到了与之前相似的问题,请问最近的新版本中有更简便的解决方法吗?

我在word表格的中间某一列定义了一个书签bookMark1,如附件中所示。
在实际应用过程中,我并不知道单元格的具体位置,只能根据书签bookMark1的信息,获取书签定义区域内第一个单元格的内容(即Test1),我尝试了许多方法,都无法正确获取,请问有什么方法可以获取吗?

Wang_Student
 
Posts: 5
Joined: Tue Aug 02, 2022 6:07 am

Fri Feb 17, 2023 9:50 am

您好,

感谢您的留言。
根据您的文档来看,您获取不到书签内容的主要原因是您添加的是一个不完整的书签,只包含了书签的开始而没有结尾。我这边在您原文档(附件中)的基础上修改了书签,使用下面的代码是可以获取到书签内容“Test1”,另外在使用MS Word插入书签时,要选中文字后点击插入书签,不要先建立书签在输入内容,这样很容易出现问题。

Code: Select all
String input = "data/newTest.docx";
    String output = "output/extractBookmarkText.txt";

    //Load Document
    Document doc = new Document();
    doc.loadFromFile(input);

    //Creates a BookmarkNavigator instance to access the bookmark
    BookmarksNavigator navigator = new BookmarksNavigator(doc);

    //Locate a specific bookmark by bookmark name
    navigator.moveToBookmark("bookMark1");
    TextBodyPart textBodyPart = navigator.getBookmarkContent();

    //Iterate through the items in the bookmark content to get the text
    for (int i = 0; i < textBodyPart.getBodyItems().getCount(); i++)
    {
        if (textBodyPart.getBodyItems().get(i) instanceof Paragraph)
        {
            Paragraph itemPara = (Paragraph)textBodyPart.getBodyItems().get(i);
            for (int j = 0; j < itemPara.getChildObjects().getCount(); j++)
            {
                if (itemPara.getChildObjects().get(j) instanceof TextRange)
                {
                    TextRange textrange = (TextRange)(itemPara.getChildObjects().get(j));
                    String text = textrange.getText();
                    //create a new TXT file to save the text
                    writeStringToTxt(text,output);
                }
            }
        }
    }

}
public static void writeStringToTxt(String content, String txtFileName) throws IOException {
    FileWriter fWriter= new FileWriter(txtFileName,true);
    try {
        fWriter.write(content);
    }catch(IOException ex){
        ex.printStackTrace();
    }finally{
        try{
            fWriter.flush();
            fWriter.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}


Sincerely
Abel
E-iceblue support team
User avatar

Abel.He
 
Posts: 1010
Joined: Tue Mar 08, 2022 2:02 am

Return to 中文技术支持