Câu hỏi Làm cách nào để chuyển đổi HTML sang RTF (Rich Text) trong .NET mà không phải trả tiền cho một thành phần?


Có một bên thứ ba hoặc lớp .NET miễn phí sẽ chuyển đổi HTML sang RTF (để sử dụng trong điều khiển Windows Forms có kích thước văn bản phong phú) không?

Yêu cầu "miễn phí" xuất phát từ thực tế là tôi chỉ làm việc trên một mẫu thử nghiệm và chỉ có thể tải BrowserControl và chỉ hiển thị HTML nếu cần (ngay cả khi nó chậm) và Developer Express sẽ tự phát hành kiểm soát sớm-ish.

Tôi không muốn học cách viết RTF bằng tay, và tôi đã biết HTML, vì vậy tôi nghĩ đây là cách nhanh nhất để có được một số mã chứng minh ra khỏi cửa một cách nhanh chóng.


32
2017-09-29 19:17


gốc




Các câu trả lời:


Trên thực tế có một đơn giản và miễn phí giải pháp: sử dụng trình duyệt của bạn, ok đây là mẹo tôi đã sử dụng:

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(); 

Điều này có thể chậm hơn so với các phương pháp khác nhưng ít nhất nó miễn phí và hoạt động!


35
2018-01-31 18:34



Đây là một giải pháp tuyệt vời. Sẽ có một thời gian chờ, nhưng tôi đoán cho các tài liệu lớn nó sẽ được hợp lý nhanh chóng, và chất lượng sẽ tốt. - Charles Stewart
Giải pháp tốt nhưng hình ảnh không được sao chép chính xác. - Amr
Đây chỉ là những gì tôi cần, cảm ơn! - Shane LeBlanc
Có lẽ cách tốt hơn để xử lý việc chờ kiểm soát trình duyệt tải chuỗi HTML là sử dụng trình xử lý sự kiện: webBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted); - rundavidrun
Có cách nào để đạt được điều tương tự bằng cách sử dụng điều khiển WebView trong windows phone 8.1 không? - Singhal2


Xem bài viết CodeProject này XHTML2RTF.


9
2018-04-16 03:03



Tuyệt vời cho XHTML, nhưng như một người sẽ đoán từ đọc tên, không hoạt động tốt cho non-XHTML / "vani HTML" ... - sager89
Tuyệt vời! Tạo ra một ứng dụng Console. Cần thêm [STAThread] vào trước phương thức main console. - dforce


Mở rộng về câu trả lời của Spartaco Tôi đã gợi ý những điều sau đây hoạt động TUYỆT VỜI!

    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
2018-02-17 21:01



Hãy chắc chắn để xem ra cho các vấn đề phân bổ bộ nhớ nếu bạn không gọi điện thoại Dispose() trên những điều khiển mà bạn tạo ra mọi lúc. - Seph
Cảm ơn @Seph. Tôi đã sửa đổi mã để tính đến điều đó. - cjbarth


Nó không phải là hoàn hảo tất nhiên, nhưng đây là mã tôi sử dụng để chuyển đổi HTML sang văn bản thuần túy.

(Tôi không phải là tác giả gốc, tôi đã điều chỉnh nó từ mã được tìm thấy trên web)

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,
                     @"&nbsp;", " ",
                     System.Text.RegularExpressions.RegexOptions.IgnoreCase);

            result = System.Text.RegularExpressions.Regex.Replace(result,
                     @"&bull;", " * ",
                     System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            result = System.Text.RegularExpressions.Regex.Replace(result,
                     @"&lsaquo;", "<",
                     System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            result = System.Text.RegularExpressions.Regex.Replace(result,
                     @"&rsaquo;", ">",
                     System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            result = System.Text.RegularExpressions.Regex.Replace(result,
                     @"&trade;", "(tm)",
                     System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            result = System.Text.RegularExpressions.Regex.Replace(result,
                     @"&frasl;", "/",
                     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,
                     @"&copy;", "(c)",
                     System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            result = System.Text.RegularExpressions.Regex.Replace(result,
                     @"&reg;", "(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;

    }

3
2017-09-30 21:11



Đã bỏ phiếu cho các lý do để giải thích một cách hùng hồn ở đây: stackoverflow.com/questions/1732348/… - Duncan Bayne
Trớ trêu thay nó là cho gần như cùng một lý do XSLT có thể dễ bị lỗi. HTML là lộn xộn. Và hiếm khi một tài liệu XML thích hợp sẵn sàng để chuyển đổi. Tôi nghi ngờ một giải pháp thích hợp sẽ kết hợp một chút regex để có được doc đủ sạch cho một phép biến đổi XSLT thích hợp. - Menefee


Có lẽ những gì bạn cần là một điều khiển để chỉnh sửa HTML?


1
2017-09-30 08:10