简体   繁体   English

将两个ODT文档合并在一起时如何维护样式格式

[英]How to maintain style formatting when merging two ODT documents together

I am working with the AODL library for C#. 我正在使用C#的AODL库。 So far I have been able to wholesale import the text of the second document into the first. 到目前为止,我已经能够将第二个文档的文本批量导入到第一个文档中。 The issue is I can't quite figure out what I need to grab to make sure the styling is also moved over to the merged document. 问题是我不能弄清楚我需要掌握什么以确保样式也移到合并文档中。 Below is the simple code I'm using to test. 以下是我用来测试的简单代码。 The closest answer I can find is Merging two .odt files from code , which somewhat answers my question, but it still doesn't tell me where I need to put the styling/ where to get it from. 我能找到的最接近的答案是从代码中合并两个.odt文件 ,这在某种程度上回答了我的问题,但仍然没有告诉我我需要在哪里放置样式/从哪里获取它。 It at least lets me know that I need to go through the styles in the second document and make sure there are not matching names in the first otherwise there will be conflicts. 这至少让我知道,我需要仔细阅读第二个文档中的样式,并确保第一个文档中没有匹配的名称,否则会发生冲突。 I'm not sure exactly what to do, and documentation has been very slim. 我不确定该怎么做,文档也很薄。 Before you suggest anything I would like to let you know that, yes, odt is the filetype I need to work with, and doing any kind of interop stuff like Microsoft does with Word is not what I'm after. 在您提出任何建议之前,我想让您知道,是的,odt是我需要使用的文件类型,而我所追求的并不是像Microsoft对Word进行的任何类型的互操作。 If there is another library out there that works similarly to AODL I'm all ears. 如果那里还有另一个库的工作方式与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");

Here is what I ended up doing to solve my issue. 这是我最终解决我的问题所要做的。 Keep in mind I have since migrated to using Java since this question was asked, as the library appears to work a little better in that language. 请记住,自从提出此问题以来,我便开始迁移到使用Java,因为该库在该语言下似乎工作得更好。

Essentially what the methods below are doing is Grabbing the Automatic Styles that are generated in each document. 本质上,下面的方法正在做的是抓住每个文档中生成的自动样式。 It iterates through the second document and finds each style node, checking for the name attribute. 它遍历第二个文档并找到每个样式节点,并检查name属性。 That name is then tagged with an extra identifier that is unique to that document, so when they are merged together they won't conflict name wise. 然后使用该文件唯一的额外标识符来标记该名称,因此将它们合并在一起时,不会在名称上产生冲突。

The mergeFontTypesToPrimaryDoc just grabs the fonts that don't already exist in the primary doc since all the fonts are referenced in the same way in the documents there is no editing to be done. mergeFontTypesToPrimaryDoc只捕获主要文档中不存在的字体,因为所有字体在文档中都以相同的方式引用,因此无需进行任何编辑。

The updateNodeChildrenStyleNames is just a recursive method that I used to make sure I get all the in line style nodes updated to remove any conflicting names between the two documents. updateNodeChildrenStyleNames只是一种递归方法,用于确保更新所有线型节点以删除两个文档之间的任何冲突名称。

This similar idea should work in C# as well. 这个类似的想法也应该在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);
        }
    }
} 

} }

I do not know how precisely it should be coded, but using 7zip i have been able to just copy the whole styles.xml from one file to another. 我不知道它应该被精确地编码,但是使用7zip我已经能够将整个styles.xml从一个文件复制到另一个文件。 Programatically it should be just as easy. 从编程上来说,它应该一样简单。 I always format my files with styles and never with direct formatting. 我总是使用样式来格式化我的文件,而永远不会使用直接格式化。 So just replacing any file is prone to eliminate the local styles. 因此,仅替换任何文件都容易消除本地样式。

I found this answer (to the question "Cleaning a stylesheet of unused styles") https://www.mobileread.com/forums/showpost.php?s=cbbee08a1204df71ec5cd88bcf222253&p=2100914&postcount=13 which iterates through all the styles in one document. 我找到了这个答案(针对“清理未使用样式的样式表”的问题) https://www.mobileread.com/forums/showpost.php?s=cbbee08a1204df71ec5cd88bcf222253&p=2100914&postcount=13可以在一个文档中迭代所有样式。 It doesn't show how to incorporate one into the other, but the backbone is clear. 它没有显示如何将一个合并到另一个中,但是骨干很清楚。

'---------------------------------------------------------- 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

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

相关问题 在C#中合并Word文档时保持格式 - Maintain formatting when merging word documents in C# 合并Word文档并保留其格式,页眉和页脚 - Merging word documents and preserve their formatting, header and footer 将单元格从Excel复制到Word时如何保持单元格的格式 - How to maintain formatting of cells when copying cells from Excel to Word 在C#中合并两个XML文档 - Merging Two XML Documents in C# 我将两个Word文档与OpenXML SDK合并,但是在将图像复制到标题中时得到了损坏的文档 - I am merging two Word documents with OpenXML SDK but get a corrupt document when copying an image into a header 实体框架Linq两个表以及格式 - Entity Framework Linq two tables together with formatting 如何序列化一个长字符串并保持格式? - how to serialize a long string and maintain the formatting? 如何使用Aspose维护或强制PDF中的货币格式 - How to maintain or force currency formatting in PDF with Aspose 将注释保存到asp.net mvc应用程序中的数据库时,如何保持注释的格式? - How do I maintain formatting of comments when I save them to the database in an asp.net mvc application? 更改任何一个元素时,如何维护RichText格式(粗体/斜体/等)? - How do I maintain RichText formatting (bold/italic/etc) when changing any one element?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM