2009-03-10 14 views
6

Ho un set di file RTF memorizzati in stringhe in C# è un modo per unirli in un documento per la stampa poiché l'utente desidera stamparli come un documento con le impostazioni di stampa visualizzate una volta. Posso usare l'interoperabilità in ufficio se necessario, ovviamente evitando che questo sia migliore.Unisci file RTF

Edit: Un'interruzione di pagina sarebbe necessaria tra ogni documento Credo di poter basta inserire \ pagina per questo però

risposta

0

Here si va (C# del codice incluso in)

+0

Questo è il motivo per cui le risposte solo ai collegamenti sono scoraggiate. Il link è attualmente morto. –

+0

@ScottChamberlain: Siamo spiacenti! Ho aggiornato il link. – anhldbk

+1

@anhldbk si prega di includere le informazioni necessarie nella risposta stessa, non posso accedere al sito Web collegato, quindi la risposta al momento non è utile per me – Breeze

4

Si dovrà rimuovere il finale} dal primo documento.

Dovresti rimuovere le sezioni {\ rtf1 ... e {fonttbl .. e {colortbl ... dal secondo documento. Potrebbe essere necessario vedere qualsiasi intestazione, i margini ecc. Che potresti avere.

Separarli da una \ pagina come dici tu.

Questo presuppone che le tabelle dei caratteri e dei colori siano uguali.

Probabilmente è meglio ottenere le impostazioni di stampa dall'utente, quindi stampare separatamente ciascun documento separatamente, se questa è un'opzione.

Documento 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 
} 

Documento 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 
} 

documenti uniti:

{\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

Questo non funziona per RTF più complessi come quelli che ho. Ho finito per usare l'interoperabilità per ora. – PeteT

+0

Questo non funzionerà anche per i documenti che non condividono esattamente le tabelle dei caratteri e dei colori – Beta033

0

Credo che ci sia anche un modo di fare questo senza entrare nei dettagli del Formato RTF. Salva i file RTF come file e utilizza l'automazione di MS Word per aprire e aggiungere documenti tra loro (quindi salvare di nuovo come RTF).

+0

Pensa che questo è l'approccio che finirò per prendere, mi chiedo solo se posso farlo senza scrivere i file temporanei separati ora. Codice – PeteT

0

Ho usato questo code two merge to rtf files, utilizzare il metodo de Unisci con percorso di file. Se hai solo il de text puoi modificarlo, ma se hai un documento più grande ti troverai in un errore di memoria. Mi dispiace per il mio inglese.

+0

per unire due file rtf –

3

Basta rimuovere la tabella di caratteri funziona solo se entrambi i documenti utilizzano lo stesso set di caratteri. Sarà necessario unire in modo univoco (unione) le tabelle dei font (font element wise) se si desidera conservare le informazioni sui font di entrambi i rtfs. Questo funzionerà per n numero di rtfs, ma ancora una volta abbiamo bisogno dell'unione delle singole tabelle dei font. Attualmente sto lavorando allo sviluppo del codice per questa unione pubblicheremo una volta pronto .. :)

Nel nostro progetto abbiamo usato anche il Oggetto Office Doc per eseguire il rendering di rtfs e beneficiare dell'automazione di Word. Ma crea una dipendenza dall'avere installato ms-word. In particolare, può sollevare problemi se il codice deve essere eseguito da un server in cui la memoria è anche un problema poiché l'uso della parola API fa sì che l'istanza di ms-word venga caricata in memoria. Ma la soluzione funziona !!

OK !! Così pronto con il codice per l'unione delle tabelle Font in due rtfs e unendole per preservare i vari caratteri. Leggere gli RTF nelle stringhe.

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

non credo che funzionerà. questo non sta aggiornando i codici nel secondo documento man mano che vengono applicati. ciò che intendo è, nel secondo documento/f2 può essere applicato ad un testo, ma/f2 è ora/f14 nella tabella unita, quindi tutti i codici/f2 nel secondo documento devono essere aggiornati a/f14 per il font in essere mantenuto. – Beta033

2

È possibile utilizzare due caselle di testo avanzate. Leggere il file rtf in una casella di testo RTF (rtb) e quindi tagliare e incollare il testo nell'altro (rtbMerged).Per esempio:

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

rimuovo soli 3 charecter dalla fine del primo file rtf, e uno dei primo carattere della lima secondo rtf e funziona bene!

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