Объединить файлы RTF - PullRequest
       20

Объединить файлы RTF

6 голосов
/ 10 марта 2009

У меня есть набор RTF, хранящихся в строках в C #, это способ объединить их в один документ для печати, так как пользователь хочет распечатать их как один документ с параметрами печати, появляющимися однажды. Я могу использовать офисное взаимодействие, если необходимо, очевидно, лучше избегать этого.

Edit: между каждым документом будет необходим разрыв страницы, я думаю, что я могу просто вставить \ страницу для этого, хотя

Ответы [ 7 ]

4 голосов
/ 10 марта 2009

Вы должны удалить трейлинг} из первого документа.

Вам придется удалить разделы {\ rtf1 ... и {fonttbl .. и {colortbl ... из второго документа. Может потребоваться посмотреть любой заголовок, поля и т. Д., Которые у вас могут быть.

Разделите их на \ страницу, как вы говорите.

Предполагается, что таблицы шрифтов и цветов совпадают.

Вероятно, лучше получить параметры печати от пользователя, а затем распечатать каждый документ отдельно, если это возможно.

Документ 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
}

Документ 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
}

Объединенные документы:

{\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
}
3 голосов
/ 30 апреля 2011

Простое удаление таблицы шрифтов будет работать только в том случае, если оба документа используют один и тот же набор шрифтов. Вам нужно будет уникальным образом объединить (объединить) таблицы шрифтов (с точки зрения элемента font), если вы хотите сохранить информацию о шрифтах обоих rtfs. Это будет работать для n числа rtfs, но опять же нам нужно объединение отдельных таблиц шрифтов. В настоящее время я работаю над разработкой кода для этого объединения, когда публикация будет готова ..:)

В нашем проекте мы также использовали объект Office Doc для рендеринга rtfs и использования автоматизации слова. Но это создает зависимость наличия установленного ms-word. В частности, это может вызвать проблемы, если код должен запускаться с сервера, где также важна память, так как использование word API приводит к загрузке экземпляра ms-word в память. Но решение работает!

Хорошо !! Итак, готов код с объединением таблиц Font в двух rtfs и объединением их для сохранения различных шрифтов. Пожалуйста, прочитайте RTF в строках.

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


}
} 
2 голосов
/ 13 октября 2012

Вы можете использовать два расширенных текстовых поля. Считайте файл rtf в одно поле расширенного текста (rtbTemp), а затем вырежьте и вставьте текст в другое (rtbMerged). Например:

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 голосов
/ 03 июня 2014

Я удаляю только 3 символа из конца первого файла RTF и один символ из первого символа второго файла RTF, и это хорошо работает!

RichTextBox r = new RichTextBox();
r.Rtf = rtf1.Rtf.Substring(0, rtf1.Rtf.Length - 3) + rtf2.Rtf.Substring(1,rtf2.Rtf.Length - 1)
0 голосов
/ 25 февраля 2011

Здесь вы идете (код C # включен в)

0 голосов
/ 17 апреля 2009

Я использовал этот код два слияния с файлами RTF , используйте метод de Merge с путем к файлу de. Если у вас есть только текст, вы можете изменить его, но если у вас есть документ большего размера, вы будете иметь ошибку памяти. Я извиняюсь за мой английский.

0 голосов
/ 10 марта 2009

Полагаю, есть способ сделать это, не вдаваясь в подробности формата RTF. Сохраните ваши RTF-файлы как файлы и используйте Automation of MS Word, чтобы открывать и добавлять документы друг к другу (а затем снова сохранять как RTF-файл).

...