如何在 C# 中将字符串转换为 RTF?

问题描述 投票:0回答:8

问题

如何将字符串“Européen”转换为 RTF 格式的字符串“Europ\'e9en”?

[TestMethod]
public void Convert_A_Word_To_Rtf()
{
    // Arrange
    string word = "Européen";
    string expected = "Europ\'e9en";
    string actual = string.Empty;

    // Act
    // actual = ... // How?

    // Assert
    Assert.AreEqual(expected, actual);
}

到目前为止我发现了什么

富文本框

RichTextBox 可用于某些事情。例子:

RichTextBox richTextBox = new RichTextBox();
richTextBox.Text = "Européen";
string rtfFormattedString = richTextBox.Rtf;

但是 rtfFormattedString 结果是整个 RTF 格式的文档,而不仅仅是字符串“Europ\'e9en”。

计算器

谷歌

我还在网上找到了很多其他资源,但没有什么能完全解决我的问题。

回答

布拉德克里斯蒂的回答

必须添加

Trim()
以删除
result
中的前面的空格。除此之外,布拉德克里斯蒂的解决方案似乎有效。

我现在会使用这个解决方案,尽管我有一种不好的直觉,因为我们必须从 RichTextBox 中使用 SubString 和 Trim 来获得 RTF 格式的字符串。

测试用例:

[TestMethod]
public void Test_To_Verify_Brad_Christies_Stackoverflow_Answer()
{
        Assert.AreEqual(@"Europ\'e9en", "Européen".ConvertToRtf());
        Assert.AreEqual(@"d\'e9finitif", "définitif".ConvertToRtf());
        Assert.AreEqual(@"\'e0", "à".ConvertToRtf());
        Assert.AreEqual(@"H\'e4user", "Häuser".ConvertToRtf());
        Assert.AreEqual(@"T\'fcren", "Türen".ConvertToRtf());
        Assert.AreEqual(@"B\'f6den", "Böden".ConvertToRtf());
}

作为扩展方法的逻辑:

public static class StringExtensions
{
    public static string ConvertToRtf(this string value)
    {
        RichTextBox richTextBox = new RichTextBox();
        richTextBox.Text = value;
        int offset = richTextBox.Rtf.IndexOf(@"\f0\fs17") + 8; // offset = 118;
        int len = richTextBox.Rtf.LastIndexOf(@"\par") - offset;
        string result = richTextBox.Rtf.Substring(offset, len).Trim();
        return result;
    }
}
c# rtf
8个回答
9
投票

RichTextBox
不总是有相同的页眉/页脚吗?您可以根据偏移位置读取内容,然后继续使用它来解析。 (我认为?如果我错了请纠正我)

有可用的库,但我个人从来没有运气好(尽管总是在完全耗尽可能性之前找到另一种方法)。此外,大多数更好的通常都包含象征性的费用。


编辑
有点骇人听闻,但这应该可以帮助您完成需要完成的工作(我希望):

RichTextBox rich = new RichTextBox();
Console.Write(rich.Rtf);

String[] words = { "Européen", "Apple", "Carrot", "Touché", "Résumé", "A Européen eating an apple while writing his Résumé, Touché!" };
foreach (String word in words)
{
    rich.Text = word;
    Int32 offset = rich.Rtf.IndexOf(@"\f0\fs17") + 8;
    Int32 len = rich.Rtf.LastIndexOf(@"\par") - offset;
    Console.WriteLine("{0,-15} : {1}", word, rich.Rtf.Substring(offset, len).Trim());
}

编辑2

RTF控制代码分解如下:

  • 标题
    • \f0
      - 使用 0-index 字体(列表中的第一个字体,通常是 Microsoft Sans Serif(在标题的字体表中注明:
      {\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}
      ))
    • \fs17
      - 字体格式,指定大小为 17(17 为半点)
  • 页脚
    • \par
      指定它是段落的结尾。

希望这能解决一些问题。 ;-)


4
投票

我找到了一个很好的解决方案,它实际上使用 RichTextBox 本身来进行转换:

private static string FormatAsRTF(string DirtyText)
{
    System.Windows.Forms.RichTextBox rtf = new System.Windows.Forms.RichTextBox();
    rtf.Text = DirtyText;
    return rtf.Rtf;
}

http://www.baltimoreconsulting.com/blog/development/easily-convert-a-string-to-rtf-in-net/


4
投票

我是这样走的:

private string ConvertString2RTF(string input)
{
    //first take care of special RTF chars
    StringBuilder backslashed = new StringBuilder(input);
    backslashed.Replace(@"\", @"\\");
    backslashed.Replace(@"{", @"\{");
    backslashed.Replace(@"}", @"\}");

    //then convert the string char by char
    StringBuilder sb = new StringBuilder();
    foreach (char character in backslashed.ToString())
    {
        if (character <= 0x7f)
            sb.Append(character);
        else
            sb.Append("\\u" + Convert.ToUInt32(character) + "?");
    }
    return sb.ToString();
}

我认为使用

RichTextBox
是:
1)矫枉过正
2)我不喜欢
RichTextBox
花了几天时间试图让它与在Word中创建的RTF文档一起工作。


1
投票

下面是一个将字符串转换为 RTF 字符串的丑陋示例:

class Program
{
    static RichTextBox generalRTF = new RichTextBox();

    static void Main()
    {
        string foo = @"Européen";
        string output = ToRtf(foo);
        Trace.WriteLine(output);
    }

    private static string ToRtf(string foo)
    {
        string bar = string.Format("!!@@!!{0}!!@@!!", foo);
        generalRTF.Text = bar;
        int pos1 = generalRTF.Rtf.IndexOf("!!@@!!");
        int pos2 = generalRTF.Rtf.LastIndexOf("!!@@!!");
        if (pos1 != -1 && pos2 != -1 && pos2 > pos1 + "!!@@!!".Length)
        {
            pos1 += "!!@@!!".Length;
            return generalRTF.Rtf.Substring(pos1, pos2 - pos1);
        }
        throw new Exception("Not sure how this happened...");
    }
}

1
投票

我知道已经有一段时间了,希望这有帮助..

在尝试了所有我可以动手的转换代码后,这段代码对我有用:

titleText 和 contentText 是填充在常规 TextBox 中的简单文本

var rtb = new RichTextBox();
rtb.AppendText(titleText)
rtb.AppendText(Environment.NewLine);
rtb.AppendText(contentText)

rtb.Refresh();

rtb.rtf 现在包含 rtf 文本。

以下代码将保存 rtf 文本并允许您打开文件,对其进行编辑,然后再次将其加载回 RichTextBox:

rtb.SaveFile(path, RichTextBoxStreamType.RichText);

1
投票

这是改进的@Vladislav Zalesak 的回答:

public static string ConvertToRtf(string text)
{
    // using default template from wiki
    StringBuilder sb = new StringBuilder(@"{\rtf1\ansi\ansicpg1250\deff0{\fonttbl\f0\fswiss Helvetica;}\f0\pard ");
    foreach (char character in text)
    {
        if (character <= 0x7f)
        {
            // escaping rtf characters
            switch (character)
            {
                case '\\':
                case '{':
                case '}':
                    sb.Append('\\');
                    break;
                case '\r':
                    sb.Append("\\par");
                    break;
            }

            sb.Append(character);
        }
        // converting special characters
        else
        {
            sb.Append("\\u" + Convert.ToUInt32(character) + "?");
        }
    }
    sb.Append("}");
    return sb.ToString();
}

0
投票

不是最优雅的,但相当优化和快速的方法:

public static string PlainTextToRtf(string plainText)
{
    if (string.IsNullOrEmpty(plainText))
        return "";

    string escapedPlainText = plainText.Replace(@"\", @"\\").Replace("{", @"\{").Replace("}", @"\}");
    escapedPlainText = EncodeCharacters(escapedPlainText);

    string rtf = @"{\rtf1\ansi\ansicpg1250\deff0{\fonttbl\f0\fswiss Helvetica;}\f0\pard ";
    rtf += escapedPlainText.Replace(Environment.NewLine, "\\par\r\n ") + ;
    rtf += " }";
    return rtf;
}

.

编码字符(波兰语)方法:

private static string EncodeCharacters(string text)
{
    if (string.IsNullOrEmpty(text))
        return "";

    return text
        .Replace("ą", @"\'b9")
        .Replace("ć", @"\'e6")
        .Replace("ę", @"\'ea")
        .Replace("ł", @"\'b3")
        .Replace("ń", @"\'f1")
        .Replace("ó", @"\'f3")
        .Replace("ś", @"\'9c")
        .Replace("ź", @"\'9f")
        .Replace("ż", @"\'bf")
        .Replace("Ą", @"\'a5")
        .Replace("Ć", @"\'c6")
        .Replace("Ę", @"\'ca")
        .Replace("Ł", @"\'a3")
        .Replace("Ń", @"\'d1")
        .Replace("Ó", @"\'d3")
        .Replace("Ś", @"\'8c")
        .Replace("Ź", @"\'8f")
        .Replace("Ż", @"\'af");
}

0
投票
private static string ConvertToRtf(string text)
{
    // Create a regular expression pattern to match non-ASCII characters
    string pattern = "[^\x00-\x7F]";
    // Use Regex.Replace to escape non-ASCII characters
    return Regex.Replace(text, pattern, m => m.Value[0] > 255 ? @"\u" + ((int)m.Value[0]).ToString() + "?" : @"\'" + ((int)m.Value[0]).ToString("X2").ToLowerInvariant());
}
© www.soinside.com 2019 - 2024. All rights reserved.