简体   繁体   English

在特定书签中使用docx4j在word doc中创建表:

[英]Create table in word doc using docx4j in specific bookmark:

I'm creating a table in specific bookmark location (means it's adisplay table in word doc), but after converting word to PDF it can't show table in PDF because of bookmark is inside a w:p !! 我正在特定书签位置创建一个表(意味着它是word doc中的显示表),但是将word转换为PDF后,由于书签位于w:p内而无法在PDF中显示表!

<w:p w:rsidR="00800BD9" w:rsidRDefault="00800BD9">  
  <w:bookmarkStart w:id="0" w:name="abc"/>
  <w:bookmarkEnd w:id="0"/>
</w:p>

Now I want to find the paragraph (using the bookmark), then replace the paragraph with the table. 现在,我想找到该段落(使用书签),然后将该段落替换为表格。

Does anybody have any suggestion? 有人有什么建议吗?

Here is my code: 这是我的代码:

    private void replaceBookmarkContents(List<Object> paragraphs,  Map<DataFieldName, String> data) throws Exception {

    Tbl table  = TblFactory.createTable(3,3,9600);
    RangeFinder rt = new RangeFinder("CTBookmark", "CTMarkupRange");
    new TraversalUtil(paragraphs, rt);

    for (CTBookmark bm : rt.getStarts()) {

        // do we have data for this one?
        if (bm.getName()==null) continue;
        String value = data.get(new DataFieldName(bm.getName()));
        if (value==null) continue;

        try {
            // Can't just remove the object from the parent,
            // since in the parent, it may be wrapped in a JAXBElement
            List<Object> theList = null;
            if (bm.getParent() instanceof P) {
                System.out.println("OK!");
                theList = ((ContentAccessor)(bm.getParent())).getContent();
            } else {
                continue;
            }

            int rangeStart = -1;
            int rangeEnd=-1;
            int i = 0;
            for (Object ox : theList) {
                Object listEntry = XmlUtils.unwrap(ox); 
                if (listEntry.equals(bm)) {
                    if (DELETE_BOOKMARK) {
                        rangeStart=i;
                    } else {
                        rangeStart=i+1;                         
                    }
                } else if (listEntry instanceof  CTMarkupRange) {
                    if ( ((CTMarkupRange)listEntry).getId().equals(bm.getId())) {
                        if (DELETE_BOOKMARK) {
                            rangeEnd=i;
                        } else {
                            rangeEnd=i-1;                           
                        }
                        break;
                    }
                }
                i++;
            }

            if (rangeStart>0) {

                // Delete the bookmark range
                for (int j=rangeStart; j>0; j--) {
                    theList.remove(j);
                }

                // now add a run
                org.docx4j.wml.R  run = factory.createR();
                run.getContent().add(table);
                theList.add(rangeStart, run);
            }

        } catch (ClassCastException cce) {
            log.error(cce.getMessage(), cce);
        }
    }
}

The problem with blindly replacing a bookmark inside a paragraph with a table is that you'll end up with w:p/w:tbl (or with your code, w:p/w:r/w:tbl!) which is not allowed by the file format. 用表格盲目地将段落内的书签替换为书签的问题是,最终将导致w:p / w:tbl(或代码,w:p / w:r / w:tbl!)允许的文件格式。

To avoid this issue, you could make the bookmark a sibling of the paragraph, or you could change your code so that once you have found a bookmark inside a paragraph, if you are replacing it with a table, you replace the parent p instead. 为避免此问题,可以将书签设为段落的同级,或者可以更改代码,以便一旦在段落内找到书签,如果将其替换为表,则可以替换父级p。

Note that bookmark find/replace is a brittle basis for document generation. 请注意,书签查找/替换是文档生成的脆弱基础。 If your requirements are other than modest, you'd be better off using content controls instead. 如果您的要求不是中等,那么最好使用内容控件。

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

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