当前位置: 首页 > 知识库问答 >
问题:

两个ODT文档合并时如何维护样式格式

彭仲卿
2023-03-14

我正在使用C#的AODL库。到目前为止,我已经能够将第二个文档的文本大量导入到第一个文档中。问题是我不知道我需要抓取什么来确保样式也移到合并的文档中。下面是我用来测试的简单代码。我能找到的最接近的答案是从代码中合并两个.odt文件,这多少回答了我的问题,但它仍然没有告诉我需要将样式放在哪里/从哪里获取。它至少让我知道我需要检查第二个文档中的样式,并确保第一个文档中没有匹配的名称,否则将会有冲突。我不确定该做什么,而且文档也很少。在您提出任何建议之前,我想让您知道,是的,odt是我需要使用的文件类型,而像Microsoft使用Word那样进行任何类型的互操作并不是我想要的。如果有其他库与AODL类似,我会洗耳恭听。

TextDocument mergeTemplateDoc = ReadContentsOfFile(mergeTemplateFileName);
TextDocument vehicleTemplateDoc = ReadContentsOfFile(vehicleTemplateFileName);

foreach (IContent piece in vehicleTemplateDoc.Content)
{
    XmlNode newNode = mergeTemplateDoc.XmlDoc.ImportNode(piece.Node,true);

    Paragraph p = ParagraphBuilder.CreateParagraphWithExistingNode(mergeTemplateDoc, newNode);

    mergeTemplateDoc.Content.Add(p);
}

mergeTemplateDoc.SaveTo("MergComplete.odt");

共有1个答案

闾丘晨
2023-03-14

这是我为解决我的问题所做的事情。请记住,自从这个问题被问到之后,我已经迁移到使用Java了,因为库在该语言中似乎工作得更好一些。

本质上,下面的方法所做的是获取在每个文档中生成的自动样式。它遍历第二个文档并查找每个style节点,检查name属性。然后,该名称被标记为一个对该文档唯一的额外标识符,因此当它们合并在一起时,它们不会在名称方面发生冲突。

mergeFontTypesToPrimaryDoc只是抓取主文档中不存在的字体,因为所有字体在文档中都以相同的方式被引用,所以不需要进行编辑。

private static void mergeStylesToPrimaryDoc(OdfTextDocument primaryDoc, OdfTextDocument secondaryDoc) throws Exception {
    OdfFileDom primaryContentDom = primaryDoc.getContentDom();
    OdfOfficeAutomaticStyles primaryDocAutomaticStyles = primaryDoc.getContentDom().getAutomaticStyles();
    OdfOfficeAutomaticStyles secondaryDocAutomaticStyles = secondaryDoc.getContentDom().getAutomaticStyles();
    //Adopt style nodes from secondary doc
    for(int i =0; i<secondaryDocAutomaticStyles.getLength();i++){
        Node style = secondaryDocAutomaticStyles.item(i).cloneNode(true);
        if(style.hasAttributes()){
            NamedNodeMap attributes = style.getAttributes();
            for(int j=0; j< attributes.getLength();j++){
                Node a = attributes.item(j);
                if(a.getLocalName().equals("name")){
                    a.setNodeValue(a.getNodeValue()+_stringToAddToStyle);
                }
            }
        }
        if(style.hasChildNodes()){
            updateNodeChildrenStyleNames(style, _stringToAddToStyle, "name");
        }


        primaryDocAutomaticStyles.appendChild(primaryContentDom.adoptNode(style));

    }
}

private static void mergeFontTypesToPrimaryDoc(OdfTextDocument primaryDoc, OdfTextDocument secondaryDoc) throws Exception {
    //Insert referenced font types that are not in the primary document you are merging into
    NodeList sdDomNodes = secondaryDoc.getContentDom().getChildNodes().item(0).getChildNodes();
    NodeList pdDomNodes = primaryDoc.getContentDom().getChildNodes().item(0).getChildNodes();
    OdfFileDom primaryContentDom = primaryDoc.getContentDom();
    Node sdFontNode=null;
    Node pdFontNode=null;
    for(int i =0; i<sdDomNodes.getLength();i++){
        if(sdDomNodes.item(i).getNodeName().equals("office:font-face-decls")){
            sdFontNode = sdDomNodes.item(i);
            break;
        }
    }
    for(int i =0; i<pdDomNodes.getLength();i++){
        Node n =pdDomNodes.item(i); 
        if(n.getNodeName().equals("office:font-face-decls")){
            pdFontNode = pdDomNodes.item(i);
            break;
        }
    }
    if(sdFontNode !=null && pdFontNode != null){
        NodeList sdFontNodeChildList = sdFontNode.getChildNodes();
        NodeList pdFontNodeChildList = pdFontNode.getChildNodes();
        List<String> fontNames = new ArrayList<String>();
        //Get list of existing fonts in primary doc
        for(int i=0; i<pdFontNodeChildList.getLength();i++){
            NamedNodeMap attributes = pdFontNodeChildList.item(i).getAttributes(); 
            for(int j=0; j<attributes.getLength();j++){
                if(attributes.item(j).getLocalName().equals("name")){
                    fontNames.add(attributes.item(j).getNodeValue());
                }
            }
        }
        //Check each font in the secondary doc to make sure it gets added if the primary doesn't have it
        for(int i=0; i<sdFontNodeChildList.getLength();i++){
            Node fontNode = sdFontNodeChildList.item(i).cloneNode(true); 
            NamedNodeMap attributes = fontNode.getAttributes();
            String fontName="";
            for(int j=0; j< attributes.getLength();j++){
                if(attributes.item(j).getLocalName().equals("name")){
                    fontName = attributes.item(j).getNodeValue();
                    break;
                }
            }
            if(!fontName.equals("") && !fontNames.contains(fontName)){
                pdFontNode.appendChild(primaryContentDom.adoptNode(fontNode));
            }

        }
    }
}

private static void updateNodeChildrenStyleNames(Node n, String stringToAddToStyle, String nodeLocalName){
    NodeList childNodes = n.getChildNodes();
    for (int i=0; i< childNodes.getLength(); i++){

        Node currentChild = childNodes.item(i);

        if(currentChild.hasAttributes()){
            NamedNodeMap attributes = currentChild.getAttributes();
            for(int j =0; j < attributes.getLength(); j++){
                Node a = attributes.item(j);
                if(a.getLocalName().equals(nodeLocalName)){
                    a.setNodeValue(a.getNodeValue() + stringToAddToStyle);
                }
            }
        }
        if(currentChild.hasChildNodes()){
            updateNodeChildrenStyleNames(currentChild, stringToAddToStyle, nodeLocalName);
        }
    }
} 
 类似资料:
  • 它工作得很好,但是它丢失了关于字体的信息--原始文件是Arial Narrow和Windings的组合(用于复选框),输出masterFile全部是TimesNewRoman。起初我怀疑insertContentFromDocumentAfter的最后一个参数,但将其改为false(几乎)中断了所有格式。我做错什么了吗?还有别的办法吗?

  • 我正在尝试制作一个小的macOS查看器应用程序,它将显示ODT(打开文档)文件的内容,但不允许以TextEdit的方式进行编辑。在一个在线教程的帮助下,我制作了一个RTF查看器,其中包含了document.swift: 我想不通的是如何让程序读取ODT数据而不是RTF数据,也找不到任何有助于解决问题的文档。所以我的问题是:我如何重写那些代码以读取ODT文件而不是RTF文件?

  • 我需要计算一个单元格在一个odt上的一个表,文件,并应用条件格式,如果值>0。不在speedsheet中,是用于writer的

  • 问题内容: 是否可以将两个JSON文档与Jackson JSON库合并?我基本上是将Jackson映射器与简单的Java映射一起使用。 我尝试搜索Google和Jackson的文档,但找不到任何东西。 问题答案: 一种方法是这样使用: 它将合并来自两个来源的数据。这只会进行浅表复制,即不会对包含的对象进行递归合并。 否则,您可能只需要将JSON读取为树(),在内容上循环并手动合并即可。无论如何,这

  • 我有两个xml文件,需要将它们合并为一个xml。以下是示例: orginal.xml文件: 使现代化xml文件: 它们应合并为如下xml文件: 实际上,我想使用更新。xml来更新原始。xml: > update.xml中的新员工应该被添加到original.xml 在更新中修改了员工信息。xml应覆盖相应的员工节点。 我对XSLT略知一二,但我的知识还不足以找出适合合并的XSLT。

  • 我正在将数百个ODT文件转换成PDF文件,一个接一个地做需要很长时间。我有一个多核的CPU。是否可以使用bash或python编写一个脚本并行地完成这些操作?有没有一种方法从命令行使用libreoffice并行化批文档转换(不确定我是否使用了正确的词)?我在Python/bash中调用了以下命令: 蒂姆