2016-05-01 7 views
1

Ich arbeite mit der AODL-Bibliothek für C#. Bisher konnte ich den Text des zweiten Dokuments in den ersten importieren. Das Problem ist, dass ich nicht genau herausfinden kann, was ich ergreifen muss, um sicherzustellen, dass der Stil auch in das zusammengeführte Dokument verschoben wird. Unten ist der einfache Code, den ich zum Testen verwende. Die nächste Antwort, die ich finden kann, ist Merging two .odt files from code, die etwas meine Frage beantwortet, aber es sagt mir immer noch nicht, wo ich das Styling setzen muss/woher ich es bekommen soll. Es lässt mich zumindest wissen, dass ich die Stile im zweiten Dokument durchgehen muss und sicherstellen muss, dass es keine übereinstimmenden Namen in der ersten gibt, da sonst Konflikte entstehen. Ich bin mir nicht sicher, was genau zu tun ist, und die Dokumentation war sehr dünn. Bevor Sie etwas vorschlagen, möchte ich Sie wissen lassen, dass der Dateityp, mit dem ich arbeiten muss, und jede Art von Interop-Material wie Microsoft mit Word nicht das ist, wonach ich suche. Wenn es eine andere Bibliothek gibt, die ähnlich wie AODL funktioniert, bin ich ganz Ohr.Wie Sie die Formatierung beim Zusammenführen zweier ODT-Dokumente beibehalten

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

Antwort

0

Hier ist, was ich getan habe, um mein Problem zu lösen. Denken Sie daran, dass ich seit der Migration auf Java umgestiegen bin, da diese Frage gestellt wurde, da die Bibliothek in dieser Sprache scheinbar etwas besser funktioniert.

Im Wesentlichen sind die folgenden Methoden greifen die automatischen Stile, die in jedem Dokument erzeugt werden. Es durchläuft das zweite Dokument und findet jeden Stilknoten, wobei er nach dem Namensattribut sucht. Dieser Name wird dann mit einem zusätzlichen Bezeichner versehen, der für dieses Dokument eindeutig ist. Wenn sie zusammengeführt werden, treten keine Namenskonflikte auf.

Mit mergeFontTypesToPrimaryDoc werden nur die Schriftarten erfasst, die noch nicht im primären Dokument vorhanden sind, da alle Schriftarten in den Dokumenten auf die gleiche Weise referenziert werden. Es ist keine Bearbeitung erforderlich.

Die updateNodeChildrenStyleNames ist nur eine rekursive Methode, die ich verwendet habe, um sicherzustellen, dass ich alle Inline-Stil-Knoten aktualisiert, um alle in Konflikt stehenden Namen zwischen den beiden Dokumenten zu entfernen.

Diese ähnliche Idee sollte auch in C# funktionieren.

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

}

-2

Ich weiß nicht, wie genau sollte sie codiert werden, aber unter Verwendung von 7-Zip-i in der Lage gewesen, nur um eine anderen die ganze styles.xml von einer Datei zu kopieren. Programmatisch sollte es genauso einfach sein. Ich formatiere meine Dateien immer mit Stilen und nie mit direkter Formatierung. Wenn Sie also nur eine Datei ersetzen, werden die lokalen Stile möglicherweise entfernt.

Ich fand diese Antwort (auf die Frage "Ein Stylesheet von unbenutzten Styles säubern") https://www.mobileread.com/forums/showpost.php?s=cbbee08a1204df71ec5cd88bcf222253&p=2100914&postcount=13 , die durch alle Stile in einem Dokument iteriert. Es zeigt nicht, wie man ineinander übergeht, aber das Rückgrat ist klar.

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

Dies ist nicht eine Antwort auf die Frage liefert. Sobald Sie genügend [Reputation] (http://stackoverflow.com/help/whats-reputation) haben, können Sie [jeden Beitrag kommentieren] (http://stackoverflow.com/help/privileges/comment); stattdessen [geben Sie Antworten, die keine Klärung durch den Fragesteller erfordern] (http://meta.stackexchange.com/questions/214173/why-doe-i-need-50-reputation-to-comment-what-can- i-do-stattdessen). - [Aus Bewertung] (/ review/low-quality-posts/15011498) –

+0

Ich verbesserte die Antwort, thx – cxs

+0

Dies beantwortet meine Frage nicht, und ist schwer zu entziffern, da ich vermute, dass dies in VB neben der Tatsache ist es ist auf Französisch.Da ich diese Frage ursprünglich gestellt habe, war es mir möglich, die Stilknoten im zweiten Dokument umzubenennen, so dass sie nicht mit dem ersten Dokument in Konflikt geraten und sie dann alle auf eins kopieren. – PTaladay