2009-03-10 11 views
6

J'ai un ensemble de fichiers RTF stockés dans des chaînes en C# est un moyen de les fusionner en un document pour l'impression que l'utilisateur veut les imprimer comme un document avec les paramètres d'impression apparaissant une fois. Je peux utiliser interop bureau si nécessaire, évitant évidemment cela est mieux.Fusionner des fichiers RTF

Edit: Un saut de page serait nécessaire entre chaque document que je pense que je peux insérer \ page pour ce que

Répondre

0

Here vous allez (C# Code de inclus dans)

+0

C'est pourquoi les réponses aux liens uniquement sont déconseillées. Le lien est actuellement mort. –

+0

@ScottChamberlain: Désolé! J'ai mis à jour le lien. – anhldbk

+1

@anhldbk s'il vous plaît inclure les informations nécessaires dans la réponse elle-même, je ne peux pas accéder au site Web lié, de sorte que la réponse n'est actuellement pas utile pour moi – Breeze

4

Vous devrez retirer la fuite} du premier document.

Vous devez supprimer les sections {\ rtf1 ... et {fonttbl .. et {colortbl ... du deuxième document. Vous devrez peut-être regarder les en-têtes, les marges, etc. que vous pourriez avoir. Séparez-les par une page comme vous le dites.

Cela suppose que les tables de polices et de couleurs sont les mêmes.

Probablement préférable d'obtenir les paramètres d'impression de l'utilisateur, puis d'imprimer chaque document séparément, si c'est une option.

Document 1:

{\rtf1\ansi\ansicpg1252\deff0\deflang5129 
{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}} 
{\colortbl;\red0\green0\blue0;} 
\margl1134\margr1134\margt1134\margb1134\sectd 
\pard 
Document One Content 
\line 
} 

Document 2:

{\rtf1\ansi\ansicpg1252\deff0\deflang5129 
{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}} 
{\colortbl;\red0\green0\blue0;} 
\margl1134\margr1134\margt1134\margb1134\sectd 
\pard 
Document Two Content 
\line 
} 

Fusion Documents:

{\rtf1\ansi\ansicpg1252\deff0\deflang5129 
{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}} 
{\colortbl;\red0\green0\blue0;} 
\margl1134\margr1134\margt1134\margb1134\sectd 
\pard 
Document One Content 

\page 

\pard 

Document Two Content 
\line 
} 
+0

Cela ne fonctionne pas pour les RTF plus complexes comme ceux que j'ai. J'ai fini par utiliser interop pour le moment. – PeteT

+0

Cela ne fonctionnera pas non plus pour les documents qui ne partagent pas exactement les polices et les tables de couleurs – Beta033

0

Je pense qu'il ya aussi une façon de le faire sans entrer dans les détails de la Format RTF. Enregistrez vos fichiers RTF sous forme de fichiers et utilisez Automation of MS Word pour ouvrir et ajouter des documents les uns aux autres (puis enregistrez-les à nouveau au format RTF).

+0

Pensez que c'est l'approche que je vais prendre, je me demande simplement si je peux le faire sans écrire les fichiers séparés temporaires maintenant. – PeteT

0

J'ai utilisé ce code two merge to rtf files, utilisez la méthode Fusionner avec le chemin des fichiers. Si vous n'avez que du texte, vous pouvez le modifier, mais si vous avez un document plus volumineux, vous aurez une erreur de mémoire. Je suis désolé pour mon anglais.

+0

code pour fusionner deux fichiers rtf –

3

Il suffit de retirer la table de police ne fonctionnera que si les deux documents utilisent le même ensemble de polices. Vous devrez fusionner de façon unique (union) les tables de polices (élément de police sage) si vous souhaitez conserver les informations de police des deux rtfs. Cela fonctionnera pour n nombre de rtfs mais encore une fois nous avons besoin de l'union de tables de polices individuelles .. Je travaille actuellement sur le développement du code pour cette union postera une fois prêt .. :)

Dans notre projet, nous avons également utilisé le Objet Office Doc pour afficher les fichiers rtfs et bénéficier de l'automatisation de Word. Mais cela crée une dépendance d'avoir MS-Word installé. En particulier, cela peut poser problème si le code doit être exécuté à partir d'un serveur où la mémoire est également un problème car l'utilisation de l'API mot entraîne l'instance de ms-mot à charger en mémoire. Mais la solution fonctionne !!

Okay !! Tellement prêt avec le code pour l'union des tables de police dans deux rtfs et les fusionnant pour préserver des polices variables. S'il vous plaît lire les RTF dans les chaînes.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Collections; 
//Arjun 02nd May 
namespace MergeRtf 
{ 
class RTFUtils 
{ 
    public static string getRTFBlock(string blockName,string rtf){ 

     int i=rtf.IndexOf(@"{\"+blockName); 
     int startOfBlock = i; 
     //Next find the end of style sheet element tag 
     Stack<char> braceHolder=new Stack<char>(); 
     braceHolder.Push('{'); 

     string stylesheetBlock = ""; 

     while (braceHolder.Count != 0&&i<rtf.Length) { 
      i++; 
      if (rtf[i] == '{') { 
       braceHolder.Push('{'); 
       continue; 
      } 
      if (rtf[i] == '}') { 
       braceHolder.Pop(); 
      } 
     } 
     if (braceHolder.Count == 0) { 
     //encountered the ending tag for stylesheet 
      stylesheetBlock = rtf.Substring(startOfBlock, i-startOfBlock+1); 
      return stylesheetBlock; 
     } 
     else 
     { 
      //Error in doc format 
      throw (new Exception("Error in doc format")); 
     } 


    } 



    public static string MergeRTFs(string rtf1,string rtf2,string mergingBreak){ 
     //mergingBreak is the type of break that will be sandwiched between the docs 
     //get the fonttbl blocks for both the documents 
     string fontTableOfDoc1 = getRTFBlock("fonttbl", rtf1); 
     string fontTableOfDoc2 = getRTFBlock("fonttbl", rtf2); 

     //get font lists 
     List<string> fontList1 = ExtractRTFFonts(fontTableOfDoc1); 
     List<string> fontList2 = ExtractRTFFonts(fontTableOfDoc2); 

     //Union the font list 
     IEnumerable<string> mergedfonts = fontList1.Union(fontList2); 
     List<string> fontList3 = new List<string>(mergedfonts); 
     string mergedFontListBlock = @"{\fonttbl"; 
     foreach (string font in fontList3) { 
      mergedFontListBlock += font; 
     } 
     mergedFontListBlock += "}"; 

     //Find location of the fonttable in doc 1 and doc 2 
     int indexOfFontTable1 = rtf1.IndexOf(@"{\fonttbl"); 
     int indexOfFontTable2 = rtf2.IndexOf(@"{\fonttbl"); 

     string rtfMerged = ""; 
     //Get rtf content before and after fonttable 
     string headerRTF1 = rtf1.Substring(0, indexOfFontTable1); 
     int endOfFontTableIndex=indexOfFontTable1 + (fontTableOfDoc1.Length-1); 
     string trailerRTF1 = rtf1.Substring(endOfFontTableIndex + 1,  rtf1.LastIndexOf('}') - (endOfFontTableIndex + 1)); //-2 to remove ending } of 1st doc 
     //create the first rtf with merged fontlist 
     rtfMerged = headerRTF1 + mergedFontListBlock + trailerRTF1; 
     //next identify trailer part after font table in rtf 2 
     string trailerRTF2 = rtf2.Substring(indexOfFontTable2 + fontTableOfDoc2.Length); 
     rtfMerged += mergingBreak + trailerRTF2; 

     return rtfMerged; 
    } 

    private static List<string> ExtractRTFFonts(string fontTableBlock) { 
     Stack<char> braces = new Stack<char>(); 
     List<string> fonts = new List<string>(); 
     int fontDefStart=0,fontDefLength; 
     braces.Push('{'); 
     int i=0; 
     while (braces.Count > 0 && i < fontTableBlock.Length) { 
      i++; 
      if (fontTableBlock[i] == '{') { 
       braces.Push('{'); 
       if (braces.Count == 2) { 
       //means font definition brace started store the position 
        fontDefStart = i; 
       } 
       continue; 
      } 
      if (fontTableBlock[i] == '}') { 
       braces.Pop(); 
       if (braces.Count == 1) { 
       //means only root level brace left identifying one font definition ended 
        fontDefLength = i - fontDefStart + 1; 
        fonts.Add(fontTableBlock.Substring(fontDefStart,fontDefLength)); 
       } 
      } 
     } 

     if (braces.Count == 0) 
     { 
      //everything is fine then 
      return fonts; 
     } 
     else { 
     //malformed font table passed 
      throw (new Exception("Malformed font table passed")); 
     } 
    } 


} 
} 
+0

je ne pense pas que cela va fonctionner. ceci ne met pas à jour les codes dans le second document tels qu'ils sont appliqués. ce que je veux dire, dans le deuxième document/f2 peut être appliqué à un texte, mais/f2 est maintenant/f14 dans la table fusionnée, donc tous les codes/f2 dans le deuxième document doivent être mis à jour/f14 pour la police être maintenu. – Beta033

2

Vous pouvez utiliser deux zones de texte enrichi. Lisez le fichier rtf dans une zone de texte enrichi (rtbTemp), puis coupez et collez le texte dans l'autre (rtbMerged).Par exemple:

RichTextBox rtbTemp = new RichTextBox(); 
RichTextBox rtbMerged = new RichTextBox(); 

string Merge(string s1, string s2) 
{ 
    rtbTemp.Rtf = s1; 
    rtbTemp.SelectAll(); 
    rtbTemp.Cut(); 
    rtbMerged.Paste(); 

    rtbMerged.AppendText(Environment.NewLine); 
    rtbMerged.AppendText(Environment.NewLine); 

    rtbTemp.Rtf = s2; 
    rtbTemp.SelectAll(); 
    rtbTemp.Cut(); 
    rtbMerged.Paste(); 

    return rtbMerged.Rtf; 
} 
0

Je ne supprimer 3 charecter de fin du premier fichier rtf, et l'un des premier caractère du second fichier rtf et il travaille bien!

RichTextBox r = new RichTextBox(); 
r.Rtf = rtf1.Rtf.Substring(0, rtf1.Rtf.Length - 3) + rtf2.Rtf.Substring(1,rtf2.Rtf.Length - 1) 
Questions connexes