2009-03-10 35 views
6

Tengo un conjunto de archivos RTF almacenados en cadenas en C# para combinarlos en un documento para imprimir, ya que el usuario desea imprimirlos como un documento con la configuración de impresión apareciendo una vez. Puedo usar la interoperabilidad de la oficina si es necesario, obviamente evitar esto es mejor.Combinar archivos RTF

Editar: Un salto de página sería necesaria entre cada documento Creo que sólo se puede insertar \ página para esto, sin embargo

Respuesta

0

Here ir (C# de código incluido en)

+0

Es por eso que se desaconsejan las respuestas de solo enlace. El enlace está actualmente muerto. –

+0

@ScottChamberlain: ¡Lo siento! He actualizado el enlace. – anhldbk

+1

@anhldbk por favor incluya la información necesaria en la respuesta en sí, no puedo acceder al sitio web vinculado, por lo que la respuesta no es útil para mí – Breeze

4

Usted tendría que quitar los modificadores} del primer documento.

Debería eliminar las secciones {\ rtf1 ... y {fonttbl .. y {colortbl ... del segundo documento. Es posible que tenga que mirar cualquier encabezado, márgenes, etc. que pueda tener.

Sepárelos por \ una página como diga.

Esto supone que la fuente y las tablas de colores son las mismas.

Probablemente sea mejor obtener la configuración de impresión del usuario y luego imprimir de forma silenciosa cada documento por separado, si esa es una opción.

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 
} 

documentos combinados:

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

Esto no funciona para los RTF más complejos como los que tengo. Terminé usando interoperabilidad por ahora. – PeteT

+0

Esto tampoco funcionará para los documentos que no comparten la fuente y las tablas de colores exactamente – Beta033

0

Creo que hay también una manera de hacer esto sin entrar en los detalles de la Formato RTF. Guarde sus archivos RTF como archivos y utilice la automatización de MS Word para abrir y anexar documentos entre sí (luego guarde de nuevo como RTF).

+0

Creo que este es el enfoque que terminaré tomando, solo me pregunto si puedo hacerlo sin escribir los archivos temporales separados ahora. Código – PeteT

0

He usado este code two merge to rtf files, use de method Merge with de path of de files. Si solo tiene texto, puede modificarlo, pero si tiene un documento más grande, tendrá un error de memoria. Lo siento por mi Inglés.

+0

para combinar dos archivos rtf –

3

sólo la eliminación de la tabla de fuentes sólo funcionará si ambos documentos utilizan el mismo conjunto de fuentes. Necesitará fusionar de manera única (unión) las tablas de fuentes (elemento de fuente sabio) si desea conservar la información de fuente de ambos rtfs. Esto funcionará para n número de rtfs pero de nuevo necesitamos la unión de tablas de fuentes individuales. Actualmente estoy trabajando en desarrollar el código para que esta unión lo publique una vez listo ... :)

En nuestro proyecto también usamos el Objeto de Office Doc para procesar rtfs y beneficiarse de la automatización de palabras. Pero crea una dependencia de tener ms-word instalado. En particular, puede plantear un problema si el código debe ejecutarse desde un servidor donde la memoria también es una preocupación, ya que el uso de la API de palabras hace que la instancia de ms-word se cargue en la memoria. ¡Pero la solución funciona!

¡Bien! Así que listo con el código para la unión de las tablas de fuentes en dos rtfs y fusionándolas para preservar fuentes variables. Lea los RTF en cadenas.

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

en este momento. No creo que esto funcione. esto no actualiza los códigos en el segundo documento a medida que se aplican. lo que quiero decir es que en el segundo documento/f2 se puede aplicar a algún texto, pero/f2 ahora/f14 en la tabla fusionada, por lo que todos los códigos/f2 en el segundo documento deben actualizarse a/f14 para que la fuente ser mantenido. – Beta033

2

Puede usar dos cuadros de texto enriquecido. Lea el archivo rtf en un cuadro de texto enriquecido (rtbTemp) y luego corte y pegue el texto en el otro (rtbMerged).Por ejemplo:

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

sólo quito 3 charecter desde el extremo del primer archivo RTF, y uno de primer carácter del segundo archivo RTF y que funcione bien!

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