Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 合并两个ODT文档时如何保持样式格式_C#_Odt_Odftoolkit_Odt.net - Fatal编程技术网

C# 合并两个ODT文档时如何保持样式格式

C# 合并两个ODT文档时如何保持样式格式,c#,odt,odftoolkit,odt.net,C#,Odt,Odftoolkit,Odt.net,我正在使用C的AODL库。到目前为止,我已经能够将第二个文档的文本批量导入第一个文档。问题是我不太清楚我需要抓取什么来确保样式也移到合并文档中。下面是我用来测试的简单代码。我能找到的最接近的答案是,这在某种程度上回答了我的问题,但它仍然没有告诉我需要将样式放在哪里/从哪里获得它。它至少让我知道我需要检查第二个文档中的样式,并确保第一个文档中没有匹配的名称,否则会有冲突。我不确定到底该做什么,而且文档也非常少。在您提出任何建议之前,我想让您知道,是的,odt是我需要使用的文件类型,而像Micros

我正在使用C的AODL库。到目前为止,我已经能够将第二个文档的文本批量导入第一个文档。问题是我不太清楚我需要抓取什么来确保样式也移到合并文档中。下面是我用来测试的简单代码。我能找到的最接近的答案是,这在某种程度上回答了我的问题,但它仍然没有告诉我需要将样式放在哪里/从哪里获得它。它至少让我知道我需要检查第二个文档中的样式,并确保第一个文档中没有匹配的名称,否则会有冲突。我不确定到底该做什么,而且文档也非常少。在您提出任何建议之前,我想让您知道,是的,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");

我不知道应该如何精确地编码,但使用7zip,我能够将整个styles.xml从一个文件复制到另一个文件。从程序上来说,它应该同样容易。 我总是用样式格式化文件,从不直接格式化。因此,仅替换任何文件都容易消除本地样式

我在清理未使用样式的样式表时发现了这个问题的答案 它迭代一个文档中的所有样式。它没有显示如何将一个合并到另一个,但主干是明确的

'---------------------------------------------------------- 03/02/2012
' Supprimer les styles personnalisés inutilisés
' d'un document texte ou d'un classeur
'---------------------------------------------------------------------
sub stylesPersoInutiles()
dim coStylesFamilles as object, oStyleFamille as object
dim oStyle as object, nomFamille as string
dim f as long, x as long
dim ts(), buf as string, iRet as integer
const SEP = ", "

    coStylesFamilles = thisComponent.StyleFamilies
    for f = 0 to coStylesFamilles.count -1
        ' Pour chaque famille
        nomFamille = coStylesFamilles.elementNames(f)
        oStyleFamille = coStylesFamilles.getByName(nomFamille)
        buf = ""
        for x = 0 to oStyleFamille.Count -1
            ' Pour chaque style
            oStyle = oStyleFamille(x)
            'xray oStyle            
            if (oStyle.isUserDefined) and (not oStyle.isInUse) then
                buf = buf & oStyle.name & SEP
            end if
        next x

        if len(buf) > len(SEP) then
            buf = left(buf, len(buf) - len(SEP))
            iRet = msgBox("Styles personnalisés non utilisés : " _
                & chr(13) & buf & chr(13) & chr(13) _
                & "Faut-il les détruire ?", 4+32+256, nomFamille)
            if iRet = 6 then
                ts = split(buf, SEP)
                for x = 0 to uBound(ts) 
                    oStyleFamille.removeByName(ts(x))
                next x
            end if
        end if
    next f
end sub

以下是我为解决我的问题所做的事情。请记住,自从有人提出这个问题以来,我已经迁移到使用Java,因为该库在该语言中的工作似乎更好一些

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

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

updateNodeChildrenStyleNames只是一个递归方法,我使用它来确保更新所有行内样式节点,以删除两个文档之间的任何冲突名称

这种类似的想法在C语言中也应该适用

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);
        }
    }
} 

}

这并没有回答我的问题,而且很难理解,因为我猜这是用VB编写的,而事实上它是用法语编写的。因为我最初问了这个问题,所以我想出了一种方法来重命名第二个文档中的样式节点,这样它们就不会与第一个文档冲突,然后将它们全部复制到一个文档中。