Как преобразовать HTML в RTF (Rich Text) в .NET без оплаты какого-либо компонента?
Есть ли бесплатный сторонний или .NET-класс, который будет конвертировать HTML в RTF (для использования в элементе управления Windows Forms с расширенным текстом)?
"Свободное" требование исходит из того факта, что я только работаю над прототипом и могу просто загрузить BrowserControl и просто визуализировать HTML, если это необходимо (даже если он медленный), и что Developer Express будет выпускать их собственный контроль в ближайшее время.
Я не хочу учиться писать RTF вручную, и я уже знаю HTML, поэтому я считаю, что это самый быстрый способ быстро получить некоторый демонстративный код.
Ответы
Ответ 1
На самом деле существует простое и свободное решение: используйте ваш браузер, хорошо, это трюк, который я использовал:
var webBrowser = new WebBrowser();
webBrowser.CreateControl(); // only if needed
webBrowser.DocumentText = *yourhtmlstring*;
while (_webBrowser.DocumentText != *yourhtmlstring*)
Application.DoEvents();
webBrowser.Document.ExecCommand("SelectAll", false, null);
webBrowser.Document.ExecCommand("Copy", false, null);
*yourRichTextControl*.Paste();
Это может быть медленнее, чем другие методы, но, по крайней мере, это бесплатно и работает!
Ответ 2
Посмотрите эту статью CodeProject на XHTML2RTF.
Ответ 3
Расширение на ответ Spartaco я внедрил следующее, которое работает GREAT!
Using reportWebBrowser As New WebBrowser
reportWebBrowser.CreateControl()
reportWebBrowser.DocumentText = sbHTMLDoc.ToString
While reportWebBrowser.DocumentText <> sbHTMLDoc.ToString
Application.DoEvents()
End While
reportWebBrowser.Document.ExecCommand("SelectAll", False, Nothing)
reportWebBrowser.Document.ExecCommand("Copy", False, Nothing)
Using reportRichTextBox As New RichTextBox
reportRichTextBox.Paste()
reportRichTextBox.SaveFile(DocumentFileName)
End Using
End Using
Ответ 4
Конечно, это не идеально, но вот код, который я использую для преобразования HTML в обычный текст.
(Я не был оригинальным автором, я адаптировал его из кода, найденного в Интернете)
public static string ConvertHtmlToText(string source) {
string result;
// Remove HTML Development formatting
// Replace line breaks with space
// because browsers inserts space
result = source.Replace("\r", " ");
// Replace line breaks with space
// because browsers inserts space
result = result.Replace("\n", " ");
// Remove step-formatting
result = result.Replace("\t", string.Empty);
// Remove repeating speces becuase browsers ignore them
result = System.Text.RegularExpressions.Regex.Replace(result,
@"( )+", " ");
// Remove the header (prepare first by clearing attributes)
result = System.Text.RegularExpressions.Regex.Replace(result,
@"<( )*head([^>])*>", "<head>",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"(<( )*(/)( )*head( )*>)", "</head>",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
"(<head>).*(</head>)", string.Empty,
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// remove all scripts (prepare first by clearing attributes)
result = System.Text.RegularExpressions.Regex.Replace(result,
@"<( )*script([^>])*>", "<script>",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"(<( )*(/)( )*script( )*>)", "</script>",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
//result = System.Text.RegularExpressions.Regex.Replace(result,
// @"(<script>)([^(<script>\.</script>)])*(</script>)",
// string.Empty,
// System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"(<script>).*(</script>)", string.Empty,
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// remove all styles (prepare first by clearing attributes)
result = System.Text.RegularExpressions.Regex.Replace(result,
@"<( )*style([^>])*>", "<style>",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"(<( )*(/)( )*style( )*>)", "</style>",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
"(<style>).*(</style>)", string.Empty,
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// insert tabs in spaces of <td> tags
result = System.Text.RegularExpressions.Regex.Replace(result,
@"<( )*td([^>])*>", "\t",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// insert line breaks in places of <BR> and <LI> tags
result = System.Text.RegularExpressions.Regex.Replace(result,
@"<( )*br( )*>", "\r",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"<( )*li( )*>", "\r",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// insert line paragraphs (double line breaks) in place
// if <P>, <DIV> and <TR> tags
result = System.Text.RegularExpressions.Regex.Replace(result,
@"<( )*div([^>])*>", "\r\r",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"<( )*tr([^>])*>", "\r\r",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"<( )*p([^>])*>", "\r\r",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// Remove remaining tags like <a>, links, images,
// comments etc - anything thats enclosed inside < >
result = System.Text.RegularExpressions.Regex.Replace(result,
@"<[^>]*>", string.Empty,
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// replace special characters:
result = System.Text.RegularExpressions.Regex.Replace(result,
@" ", " ",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"•", " * ",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"‹", "<",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"›", ">",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"™", "(tm)",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"⁄", "/",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"<", "<",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@">", ">",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"©", "(c)",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
@"®", "(r)",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// Remove all others. More can be added, see
// http://hotwired.lycos.com/webmonkey/reference/special_characters/
result = System.Text.RegularExpressions.Regex.Replace(result,
@"&(.{2,6});", string.Empty,
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// make line breaking consistent
result = result.Replace("\n", "\r");
// Remove extra line breaks and tabs:
// replace over 2 breaks with 2 and over 4 tabs with 4.
// Prepare first to remove any whitespaces inbetween
// the escaped characters and remove redundant tabs inbetween linebreaks
result = System.Text.RegularExpressions.Regex.Replace(result,
"(\r)( )+(\r)", "\r\r",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
"(\t)( )+(\t)", "\t\t",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
"(\t)( )+(\r)", "\t\r",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
result = System.Text.RegularExpressions.Regex.Replace(result,
"(\r)( )+(\t)", "\r\t",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// Remove redundant tabs
result = System.Text.RegularExpressions.Regex.Replace(result,
"(\r)(\t)+(\r)", "\r\r",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// Remove multible tabs followind a linebreak with just one tab
result = System.Text.RegularExpressions.Regex.Replace(result,
"(\r)(\t)+", "\r\t",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// Initial replacement target string for linebreaks
string breaks = "\r\r\r";
// Initial replacement target string for tabs
string tabs = "\t\t\t\t\t";
for (int index = 0; index < result.Length; index++) {
result = result.Replace(breaks, "\r\r");
result = result.Replace(tabs, "\t\t\t\t");
breaks = breaks + "\r";
tabs = tabs + "\t";
}
// Thats it.
return result;
}
Ответ 5
Возможно, вам нужно элемент управления для редактирования HTML?
Ответ 6
TL; DR: Я рекомендую использовать OpenXml
формат и HtmlToOpenXml
NuGet пакет, если это возможно.
Microsoft Word COM
Я на самом деле не слишком много изучал эту тему, так как мой вариант использования - использовать функциональность на сервере, что делает COM-компоненты не лучшим выбором.
XHTML2RTF
Как упомянул @JonathanParker, вы можете использовать эту библиотеку codeproject.
Недостатки:
- Ограниченная поддержка HTML и CSS
- Не совсем .NET
- ...
Веб-браузер Windows Forms
Как упомянул @Spartaco, вы можете использовать элемент управления Windows Forms WebBrowser
.
Недостатки:
- Ссылка на System.Windows.Forms
- Использует копирование и вставка (проблематично для многопоточности)
- Работает только в потоке STA
Не поддерживаемые функции включают в себя:
- шрифты
- Цвета
- Нумерованные списки
- Зачеркнутый (
del
element) - ...
DevExpress
Пример кода "Paul V" из центра поддержки devexpress. (03.02.2015)
public String ConvertRTFToHTML(String RTF)
{
MemoryStream ms = new MemoryStream();
StreamWriter writer = new StreamWriter(ms);
writer.Write(RTF);
writer.Flush();
ms.Position = 0;
String output = "";
HtmlEditorExtension.Import(HtmlEditorImportFormat.Rtf, ms, (s, enumerable) => output = s);
return output;
}
public String ConvertHTMLToRTF(String Html)
{
MemoryStream ms = new MemoryStream();
var editor = new ASPxHtmlEditor { Html = html };
editor.Export(HtmlEditorExportFormat.Rtf, ms);
ms.Position = 0;
StreamReader reader = new StreamReader(ms);
return reader.ReadToEnd();
}
Или вы можете использовать тип RichEditDocumentServer
как показано в этом примере.
Неизвестно, что на самом деле поддерживается.
Недостатки:
- Цена
- Довольно много ссылок на одну маленькую вещь
- Больше?
Не поддерживаемые функции включают в себя:
- Зачеркнутый (
del
element)
SautinSoft
public string ConvertHTMLToRTF(string html)
{
SautinSoft.HtmlToRtf h = new SautinSoft.HtmlToRtf();
return h.ConvertString(htmlString);
}
public string ConvertRTFToHTML(string rtf)
{
SautinSoft.RtfToHtml r = new SautinSoft.RtfToHtml();
byte[] bytes = Encoding.ASCII.GetBytes(rtf);
r.OpenDocx(bytes );
return r.ToHtml();
}
Больше примеров и вариантов конфигурации можно найти здесь и здесь.
Поддерживается следующее:
- HTML 3.2
- HTML 4.01
- HTML 5
- CSS
- XHTML
Недостатки:
- Я не уверен, насколько активна разработка
- Цена
Использование базы знаний:
DIY
Если вы хотите поддерживать только ограниченную функциональность, вы можете написать свой собственный конвертер. Я бы не рекомендовал это, если поддерживаемый набор функций слишком велик.
У меня есть небольшой пример проекта, но только в образовательных целях в его текущем состоянии.
OpenXml
Если формат OpenXml также подходит для вашего случая использования, вы можете использовать пакет nuget HtmlToOpenXml. Он бесплатный и поддерживает все функции, с которыми я тестировал другие решения.
Проект основан на Open Xml SDK от Microsoft и кажется активным.
public static byte[] ConvertHtmlToOpenXml(string html)
{
using (var generatedDocument = new MemoryStream())
{
using (var package = WordprocessingDocument.Create(generatedDocument, WordprocessingDocumentType.Document))
{
var mainPart = package.MainDocumentPart;
if (mainPart == null)
{
mainPart = package.AddMainDocumentPart();
new Document(new Body()).Save(mainPart);
}
var converter = new HtmlConverter(mainPart);
converter.ParseHtml(html);
mainPart.Document.Save();
}
return generatedDocument.ToArray();
}
}
Ответ 7
Я рекомендую консольный инструмент под названием Pandoc. Это не компонент, это довольно большой пакет конверсии. Я использую его для преобразования между HTML и LaTeX. Это просто потрясающе.
Полный список поддерживаемых форматов вы можете найти на странице программы.
Чтобы преобразовать HTML-документ в формат RTF, вы пишете на консоли:
pandoc filename.html -f html -t rtf -s -o filename.rtf