Как преобразовать строку в RTF в C #? - PullRequest
13 голосов
/ 25 января 2011

Вопрос

Как преобразовать строку "Européen" в строку "Europ \ 'e9en" в формате RTF?

[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 richTextBox = new RichTextBox();
richTextBox.Text = "Européen";
string rtfFormattedString = richTextBox.Rtf;

Но тогда rtfFormattedString оказывается всем документом в формате RTF, а не просто строкой "Europ \ 'e9en".

Stackoverflow

Google

Я также нашел множество других ресурсов в сети, но ничего не решило мою проблему.

Ответ

Ответ Брэда Кристи

Пришлось добавить Trim(), чтобы удалить предыдущий пробел в result.Помимо этого, решение Брэда Кристи, кажется, работает.

Я пока попробую с этим решением, хотя у меня плохое настроение, так как нам нужно SubString и обрезать черт из RichTextBox, чтобы получить 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;
    }
}

Ответы [ 6 ]

7 голосов
/ 25 января 2011

Не всегда ли 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 указывает, что это конец абзаца.

Надеюсь, это прояснит некоторые вещивверх.; -)

3 голосов
/ 21 ноября 2013

Вот как я поступил:

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 после нескольких днейпытаясь заставить его работать с документом RTF, созданным в Word.

1 голос
/ 15 июня 2016

Я нашел хорошее решение, которое на самом деле использует 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/

1 голос
/ 03 октября 2015

Я знаю, что это было какое-то время, надеюсь, это поможет ..

Этот код работает для меня после того, как я попробовал каждый конверсионный код, которым я мог бы воспользоваться:

простой текст, заполненный обычным 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 голос
/ 25 января 2011

Ниже приведен ужасный пример преобразования строки в строку 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...");
    }
}
0 голосов
/ 31 января 2013

Не самый элегантный, но довольно оптимальный и быстрый метод:

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