简体   繁体   English

使用Docx4j从Word文档中删除表格

[英]Deleting table from word document using Docx4j

My word document has two tables and I am trying to delete last table with following code: 我的Word文档有两个表,并且我尝试使用以下代码删除最后一个表:

public static void removeTable() throws Docx4JException, JAXBException {
    File doc = new File("D:\\Hello.docx");
    WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(doc);
    MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
    String xpath = "//w:tbl";
    List<Object> list = mainDocumentPart.getJAXBNodesViaXPath(xpath, false);

    if(list.size()==2){
        Tbl tbl = (Tbl) XmlUtils.unwrap(list.get(list.size()-1));
        mainDocumentPart.getContent().remove(tbl.getParent());
        wordMLPackage.save(new java.io.File("D:\\Hello.docx"));
        System.out.println(list.size());
    }
}

But nothing is happening to my document. 但是我的文档没有任何反应。 Can anybody help me in this regard? 在这方面有人可以帮助我吗? Thanks 谢谢

I used this code as base. 我使用代码作为基础。

A working solution: 一个可行的解决方案:

public class RemoveLastTable {

    public static void main(String[] args) throws Docx4JException {
        File doc = new File("d:\\tmp\\tables.docx");
        WordprocessingMLPackage pkg = WordprocessingMLPackage.load(doc);
        removeLastTable(pkg, "d:\\tmp\\tables_updated.docx");

    }

    public static void removeLastTable(WordprocessingMLPackage wordMLPackage, String outFile) throws Docx4JException {

        Body body = wordMLPackage.getMainDocumentPart().getContents().getBody();
        List<Object> tables = getAllElementFromObject(body, Tbl.class);
        int indexTableToRemove = tables.size() - 1;
        Tbl tableToRemove = (Tbl) tables.get(indexTableToRemove);
        body.getContent().remove(tableToRemove.getParent());
        wordMLPackage.save(new File(outFile));
    }

    private static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {
        List<Object> result = new ArrayList<>();
        if (obj instanceof JAXBElement) {
            obj = ((JAXBElement<?>) obj).getValue();
        }

        if (obj.getClass().equals(toSearch)) {
            result.add(obj);
        }

        if (obj instanceof ContentAccessor) {
            List<?> children = ((ContentAccessor) obj).getContent();
            for (Object child : children) {
                result.addAll(getAllElementFromObject(child, toSearch));
            }

        }
        return result;
    }
}

However the saving of the updated document is not perfect, my Word 2016 (Office 365) was not able to read the result, only after doing recovery. 但是,更新文档的保存并不完美,我的Word 2016(Office 365)仅在执行恢复后才能读取结果。

First, specify the item you want to delete (in the list of objects your XPath returned). 首先,指定要删除的项目(在XPath返回的对象列表中)。

 Object deleteMe = list.get(1);

Use the code: 使用代码:

        Object parent = getParent(deleteMe);
        if (parent instanceof ContentAccessor) {
            boolean result = ((ContentAccessor)parent).getContent().remove(deleteMe);
            System.out.println("Deleted? " + result);
        } else {
            System.out.println("TODO: get content list from " + parent.getClass().getName());               
        }

with a little helper method: 用一些辅助方法:

private Object getParent(Object o) {    
    return ((Child)XmlUtils.unwrap(o)).getParent();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM