Domanda

Ho un set di RTF archiviati in stringhe in C # è il loro modo di unirli in un documento per la stampa poiché l'utente vuole stamparli come un documento con le impostazioni di stampa che appaiono una volta. Posso usare l'interoperabilità in ufficio se necessario, ovviamente evitando che sia meglio.

Modifica: sarebbe necessaria un'interruzione di pagina tra ogni documento che penso di poter semplicemente inserire \ page per questo

È stato utile?

Soluzione

Qui vai (codice C # incluso in)

Altri suggerimenti

Dovresti rimuovere il trascinamento} dal primo documento.

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

Separali da una \ pagina come dici tu.

Ciò presuppone che le tabelle dei caratteri e dei colori siano uguali.

Probabilmente meglio ottenere le impostazioni di stampa dall'utente quindi stampare silenziosamente ogni 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
}

La semplice rimozione della tabella dei caratteri funzionerà solo se entrambi i documenti utilizzano lo stesso set di caratteri. Sarà necessario unire in modo univoco (unione) le tabelle dei caratteri (elemento dei caratteri saggio) se si desidera conservare le informazioni sui caratteri di entrambi gli RTF. Questo funzionerà per n numero di RTF, ma ancora una volta abbiamo bisogno dell'unione delle singole tabelle dei caratteri .. Attualmente sto lavorando allo sviluppo del codice per questa unione che pubblicherà una volta pronto .. :)

Nel nostro progetto abbiamo anche usato l'oggetto Office Doc per rendere RTF e trarre vantaggio dall'automazione di Word. Ma crea una dipendenza con l'installazione di ms-word. In particolare può sollevare problemi se il codice deve essere eseguito da un server in cui anche la memoria è un problema poiché l'utilizzo dell'API di parole provoca il caricamento dell'istanza di ms-word in memoria. Ma la soluzione funziona !!

Va bene !! Quindi, pronto con il codice per l'unione delle tabelle dei font in due RTF e unendole per preservare i vari tipi di caratteri ... Leggi le RTF in 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"));
        }
    }


}
} 

Puoi usare due caselle rich text. Leggi il file rtf in una casella rich text (rtbTemp), quindi taglia e incolla il testo nell'altra (rtbMerged). Ad 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;
}

Suppongo che ci sia anche un modo per farlo senza entrare nei dettagli del formato RTF. Salvare i file RTF come file e utilizzare l'automazione di MS Word per aprire e aggiungere documenti tra loro (quindi salvare di nuovo come RTF).

Ho usato questo codice due unisci in file RTF , usa il metodo Unisci con il percorso dei file. Se hai solo de text puoi modificarlo, ma se hai un documento più grande avrai un errore di memoria. Mi dispiace per il mio inglese.

Rimuovo solo 3 caratteri dalla fine del primo file RTF e uno dei primi caratteri del secondo file 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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top