7

我有一组存储在 C# 中的字符串中的 RTF 是他们将这些合并到一个文档中进行打印的一种方式,因为用户希望将它们打印为一个文档,并且打印设置出现一次。如有必要,我可以使用 office interop,显然避免这种情况会更好。

编辑:每个文档之间都需要分页符,我认为我可以为此插入 \page

4

7 回答 7

5

您必须从第一个文档中删除尾随 }。

您必须从第二个文档中删除 {\rtf1... 和 {fonttbl.. 和 {colortbl... 部分。可能需要查看您可能拥有的任何标题、边距等。

如您所说,用 \page 将它们分开。

这假设字体和颜色表是相同的。

如果可以的话,最好从用户那里获取打印设置,然后单独打印每个文档。

文件 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
}
于 2009-03-10T00:49:03.923 回答
3

仅当两个文档使用相同的字体集时,仅删除字体表才有效。如果要保留两个 rtfs 的字体信息,则需要唯一地合并(联合)字体表(字体元素)。这将适用于 n 个 rtfs,但我们再次需要单个字体表的联合。我目前正在开发这个联合的代码,一旦准备好就会发布。:)

在我们的项目中,我们还使用 Office Doc 对象来呈现 rtfs 并从 word 的自动化中受益。但它创建了安装 ms-word 的依赖关系。特别是如果代码需要从内存也是一个问题的服务器运行,它可能会引发问题,因为使用 word API 会导致 ms-word 的实例被加载到内存中。但解决方案确实有效!!

好的!!准备好在两个 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"));
        }
    }


}
} 
于 2011-04-29T22:17:46.487 回答
2

您可以使用两个富文本框。将 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;
}
于 2012-10-13T15:33:33.757 回答
1

我只从第一个 rtf 文件的末尾删除 3 个字符,以及第二个 rtf 文件的第一个字符,它工作得很好!

RichTextBox r = new RichTextBox();
r.Rtf = rtf1.Rtf.Substring(0, rtf1.Rtf.Length - 3) + rtf2.Rtf.Substring(1,rtf2.Rtf.Length - 1)
于 2014-06-03T16:40:43.143 回答
0

我想还有一种方法可以做到这一点,而无需深入了解 RTF 格式的细节。将您的 RTF 保存为文件并使用 MS Word 的自动化打开文档并将文档彼此附加(然后再次另存为 RTF)。

于 2009-03-10T01:21:41.380 回答
0

我已经使用此代码两次合并到 rtf 文件,使用 de 方法 Merge 与 de 文件的 de 路径。如果你只有文本,你可以修改它,但如果你有更大的文档,你会出现记忆错误。我很抱歉我的英语。

于 2009-04-17T12:41:06.560 回答
-3

给你(包含 C# 代码)

于 2011-02-25T05:09:16.343 回答