Java 在特定书签中使用docx4j在word文档中创建表格:

Java 在特定书签中使用docx4j在word文档中创建表格:,java,docx4j,Java,Docx4j,我正在特定的书签位置创建一个表(意味着它是word文档中的一个显示表),但在将word转换为PDF后,它无法在PDF中显示该表,因为书签位于w:p <w:p w:rsidR="00800BD9" w:rsidRDefault="00800BD9"> <w:bookmarkStart w:id="0" w:name="abc"/> <w:bookmarkEnd w:id="0"/> </w:p> 现在我想找到段落(使用书签),然后用

我正在特定的书签位置创建一个表(意味着它是word文档中的一个显示表),但在将word转换为PDF后,它无法在PDF中显示该表,因为书签位于
w:p

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

现在我想找到段落(使用书签),然后用表格替换段落

有人有什么建议吗

这是我的密码:

    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);
        }
    }
}
private void replaceBookmark内容(列表段落、地图数据)引发异常{
Tbl table=TblFactory.createTable(3,39600);
测距仪rt=新测距仪(“CTBookmark”、“CTMarkupRange”);
新的TraversalUtil(段落,rt);
for(CTBookmark bm:rt.getStarts()){
//我们有这方面的数据吗?
如果(bm.getName()==null)继续;
字符串值=data.get(新的DataFieldName(bm.getName());
如果(值==null)继续;
试一试{
//不能只是从父对象中删除对象,
//因为在父级中,它可能被包装在JAXBElement中
List-theList=null;
if(P的bm.getParent()实例){
System.out.println(“OK!”);
列表=((ContentAccessor)(bm.getParent()).getContent();
}否则{
继续;
}
int rangeStart=-1;
int rangeEnd=-1;
int i=0;
用于(对象框:列表){
对象listEntry=XmlUtils.unwrap(ox);
if(列表输入等于(bm)){
如果(删除书签){
rangeStart=i;
}否则{
rangeStart=i+1;
}
}else if(CTMarkupRange的listEntry实例){
if(((CTMarkupRange)listEntry).getId()等于(bm.getId()){
如果(删除书签){
rangeEnd=i;
}否则{
rangeEnd=i-1;
}
打破
}
}
i++;
}
如果(范围开始>0){
//删除书签范围
对于(int j=rangeStart;j>0;j--){
列表。移除(j);
}
//现在添加跑步记录
org.docx4j.wml.R run=factory.createR();
run.getContent().add(表);
添加(范围开始、运行);
}
}捕获(ClassCastException cce){
log.error(cce.getMessage(),cce);
}
}
}

盲目地将段落内的书签替换为表格的问题是,您最终将得到文件格式不允许的w:p/w:tbl(或代码w:p/w:r/w:tbl!)

为了避免此问题,您可以将书签设置为段落的同级,或者更改代码,以便在段落中找到书签后,如果要将其替换为表,则可以替换父级p


请注意,书签查找/替换是文档生成的脆弱基础。如果您的需求不是适度的,最好使用内容控件。

可能您需要自定义从doc到pdf的转换。请您建议如何在此代码中用表替换父p。假设p由bm.getParent()给出,它应该在您的列表段落中,在这种情况下,它只是替换列表中的一个项目(Java集合)。正如您所说的,我使用Java集合将段落替换为表,它可以转换为DOCX文件(但不显示表边框)。转换为PDF时,其抛出异常: