2008-09-29 7 views
32

Czy istnieje bezpłatna trzecia strona lub klasa .NET, która skonwertuje kod HTML na format RTF (w przypadku użycia w formancie Windows Forms obsługującym formaty rich-text)?Jak przekonwertować HTML na RTF (Rich Text) w .NET bez płacenia za komponent?

Wymóg "darmowy" wynika z faktu, że pracuję tylko nad prototypem i mogę po prostu załadować BrowserControl i po prostu wyrenderować HTML w razie potrzeby (nawet jeśli jest wolny) i że program Developer Express będzie zwolnienie własnej kontroli wkrótce.

Nie chcę nauczyć się pisać ręcznie RTF, a ja już znam HTML, więc myślę, że jest to najszybszy sposób szybkiego szybkiego otwarcia kodu.

Odpowiedz

34

Właściwie nie jest proste i darmo rozwiązanie: użyć przeglądarki, ok to jest sztuczka użyłem:

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

To może być wolniejszy niż w przypadku innych metod, ale przynajmniej jest za darmo i działa!

+0

To jest świetne rozwiązanie. Nastąpi opóźnienie, ale myślę, że w przypadku dużych dokumentów będzie to dość szybko, a jakość będzie dobra. –

+0

Ładne obejście, ale zdjęcia nie zostały skopiowane poprawnie. – Amr

+0

To jest to, czego potrzebowałem, dzięki! –

3

Oczywiście nie jest idealny, ale oto kod, którego używam do konwersji HTML na zwykły tekst.

(I nie był oryginalny autor, ja dostosować go z kodu znalezionego w internecie)

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; 

    } 
+8

downvoted z powodów tak wymownie wyjaśnione tutaj: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 –

+0

Ironicznie to z prawie tych samych powodów XSLT może być podatny na błędy. HTML jest brudny. I rzadko jest to odpowiedni dokument XML gotowy do transformacji. Podejrzewam, że właściwe rozwiązanie zawierałoby trochę wyrażeń regularnych, aby dokument był wystarczająco czysty, aby uzyskać właściwą transformację XSLT. – Menefee

8

Sprawdź ten artykuł CodeProject na XHTML2RTF.

+0

Świetne dla XHTML, ale jak można się domyślić po przeczytaniu nazwy, nie działa tak dobrze dla nie-XHTML/"vanilla HTML" ... – sager89

+0

Awesome! Zrobiłem z tego aplikację konsolową. Potrzebne do dodania [STAThread] przed główną metodą konsoli. – dforce

4

Rozszerzając odpowiedź Spartaco, wprowadziłem w życie następujące rzeczy, które działają WIELKI!

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 
+1

Pamiętaj, aby uważać na problemy z przydzielaniem pamięci, jeśli nie wywołujesz funkcji "Dispose()" na tych kontrolach, które tworzysz przez cały czas. – Seph

+0

Dzięki @Seph. Zmodyfikowałem kod, aby to uwzględnić. – cjbarth

Powiązane problemy