2010-05-12 10 views
62

Mi piacerebbe sapere se ITextSharp ha la capacità di convertire HTML in PDF. Tutto quello che convertirò sarà semplicemente testo, ma sfortunatamente c'è poca o nessuna documentazione su ITextSharp, quindi non posso determinare se questa sarà una soluzione praticabile per me.ITextSharp HTML in PDF?

Se non può farlo, qualcuno può indicarmi alcune buone librerie .net libere che possono prendere un semplice documento HTML in chiaro e convertirlo in un pdf?

tia.

risposta

28

dopo aver eseguito alcuni scavi ho trovato un buon modo per ottenere ciò che mi serve con ITextSharp.

Ecco alcuni esempi di codice se vi aiuterà chiunque altro al futuro:

protected void Page_Load(object sender, EventArgs e) 
{ 
    Document document = new Document(); 
    try 
    { 
     PdfWriter.GetInstance(document, new FileStream("c:\\my.pdf", FileMode.Create)); 
     document.Open(); 
     WebClient wc = new WebClient(); 
     string htmlText = wc.DownloadString("http://localhost:59500/my.html"); 
     Response.Write(htmlText); 
     List<IElement> htmlarraylist = HTMLWorker.ParseToList(new StringReader(htmlText), null); 
     for (int k = 0; k < htmlarraylist.Count; k++) 
     { 
      document.Add((IElement)htmlarraylist[k]); 
     } 

     document.Close(); 
    } 
    catch 
    { 
    } 
} 
+4

Probabilmente non si vuole scrivere l'output su un percorso fisso come si sta facendo con un'app web. Otterrai contesa di risorse contro quel singolo file sotto carico. Usa un MemoryStream o un file temporaneo ceduto dal sistema operativo (assicurati di eliminare il file temporaneo quando hai finito con esso). Come creare un file temporaneo: http://msdn.microsoft.com/en-us/library/system.io.path.gettempfilename.aspx – ntcolonel

+2

Riferimento oggetto non impostato su un'istanza di un oggetto. alla lista htmlarraylist = HTMLWorker.ParseToList (new StringReader (htmlText), null); – viento

+0

ciao @Kyle ti prego di aiutarmi: http: //stackoverflow.com/questions/20950236/how-to-insert-html-markup-using-itextsharp-for-creating-pdf-using-c –

65

mi sono imbattuto la stessa domanda un paio di settimane fa e questo è il risultato di quello che ho trovato. Questo metodo esegue una rapida copia di HTML in un PDF. Molto probabilmente il documento richiederà un po 'di formattazione del formato.

private MemoryStream createPDF(string html) 
{ 
    MemoryStream msOutput = new MemoryStream(); 
    TextReader reader = new StringReader(html); 

    // step 1: creation of a document-object 
    Document document = new Document(PageSize.A4, 30, 30, 30, 30); 

    // step 2: 
    // we create a writer that listens to the document 
    // and directs a XML-stream to a file 
    PdfWriter writer = PdfWriter.GetInstance(document, msOutput); 

    // step 3: we create a worker parse the document 
    HTMLWorker worker = new HTMLWorker(document); 

    // step 4: we open document and start the worker on the document 
    document.Open(); 
    worker.StartDocument(); 

    // step 5: parse the html into the document 
    worker.Parse(reader); 

    // step 6: close the document and the worker 
    worker.EndDocument(); 
    worker.Close(); 
    document.Close(); 

    return msOutput; 
} 
+10

Per evitare che qualcun altro debba scavare nella documentazione, notare che dalla 5.1.1, HTMLWorker può essere trovato in iTextSharp.text.html.simpleparser. –

+68

Perché le persone non usano mai le istruzioni "using" negli esempi di codice C#? – cbp

+5

@cbp In genere, si chiama un metodo come questo in una dichiarazione di dichiarazione using. ex. 'using (MemoryStream stream = createPDF (html)) {}' – Jonathan

3

Il codice di cui sopra sarà certamente di aiuto a convertire HTML a PDF, ma non riuscirà se il codice del HTML ha tag IMG con i relativi percorsi. La libreria iTextSharp non converte automaticamente i percorsi relativi in ​​assoluti.

Ho provato il codice precedente e ho aggiunto del codice per occuparmi anche dei tag IMG.

È possibile trovare il codice qui per il vostro riferimento: http://www.am22tech.com/html-to-pdf/

+0

Identifica il problema, ma la soluzione a cui stai facendo riferimento con IImageProvider restituisce il seguente errore 'Impossibile trovare una parte del percorso 'C: \ intl \ en_ALL \ images \ srpr \ logo1w.png'' quando provo a genera PDF leggendo HTML da 'www.google.com'. – cusman

11

Ecco quello che ero in grado di ottenere lavorando sulla versione 5.4.2 (dalla NuGet installazione) per restituire una risposta PDF da un mvc asp.net controller. Potrebbe essere modificato per usare un FileStream invece di MemoryStream per l'output se è ciò che è necessario.

ho posto qui perché è un esempio completo di utilizzo iTextSharp corrente per l'html -> conversione PDF (immagini trascurando, non ho guardato in quel dato che il mio utilizzo non lo richiede)

E ' usa iTextSharp's XmlWorkerHelper, quindi l'hmtl in entrata deve essere XHTML valido, quindi potrebbe essere necessario eseguire qualche correzione a seconda dell'input.

using iTextSharp.text.pdf; 
using iTextSharp.tool.xml; 
using System.IO; 
using System.Web.Mvc; 

namespace Sample.Web.Controllers 
{ 
    public class PdfConverterController : Controller 
    { 
     [ValidateInput(false)] 
     [HttpPost] 
     public ActionResult HtmlToPdf(string html) 
     {   

      html = @"<?xml version=""1.0"" encoding=""UTF-8""?> 
       <!DOCTYPE html 
        PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN"" 
        ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd""> 
       <html xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en""> 
        <head> 
         <title>Minimal XHTML 1.0 Document with W3C DTD</title> 
        </head> 
        <body> 
        " + html + "</body></html>"; 

      var bytes = System.Text.Encoding.UTF8.GetBytes(html); 

      using (var input = new MemoryStream(bytes)) 
      { 
       var output = new MemoryStream(); // this MemoryStream is closed by FileStreamResult 

       var document = new iTextSharp.text.Document(iTextSharp.text.PageSize.LETTER, 50, 50, 50, 50); 
       var writer = PdfWriter.GetInstance(document, output); 
       writer.CloseStream = false; 
       document.Open(); 

       var xmlWorker = XMLWorkerHelper.GetInstance(); 
       xmlWorker.ParseXHtml(writer, document, input, null); 
       document.Close(); 
       output.Position = 0; 

       return new FileStreamResult(output, "application/pdf"); 
      } 
     } 
    } 
} 
+0

Grazie per questo, fornisce PDF più nitidi di HtmlRenderer e PDFSharp. Ho controllato, il tuo codice supporta le immagini. L'ho fatto per testare html = "" –

+0

@DavidSilvaSmith Buono a sapersi, grazie! –

6

Io preferisco usare un altro libreria chiamata Pechkin perché è in grado di convertire HTML banale non (che ha anche classi CSS). Ciò è possibile perché questa libreria utilizza il motore di layout WebKit utilizzato anche da browser come Chrome e Safari.

ho dettagliato sul mio blog la mia esperienza con Pechkin: http://codeutil.wordpress.com/2013/09/16/convert-html-to-pdf/

10

risponderei di mightymada un up'd se ho avuto la reputazione - ho appena implementato un HTML asp.net alla soluzione PDF utilizzando Pechkin. i risultati sono meravigliosi

V'è un pacchetto NuGet per Pechkin, ma come sopra manifesto cita nel suo blog (http://codeutil.wordpress.com/2013/09/16/convert-html-to-pdf/ - Spero che lei non mente mi reinserire esso), c'è una perdita di memoria che è stato risolto in questo ramo:

https://github.com/tuespetre/Pechkin

Il blog precedente contiene istruzioni specifiche su come includere questo pacchetto (è una DLL a 32 bit e richiede .net4).ecco il mio codice Il codice HTML in entrata è in realtà montato tramite HTML Agility Pack (Sto automatizzando generazioni fattura):

public static byte[] PechkinPdf(string html) 
{ 
    //Transform the HTML into PDF 
    var pechkin = Factory.Create(new GlobalConfig()); 
    var pdf = pechkin.Convert(new ObjectConfig() 
          .SetLoadImages(true).SetZoomFactor(1.5) 
          .SetPrintBackground(true) 
          .SetScreenMediaType(true) 
          .SetCreateExternalLinks(true), html); 

    //Return the PDF file 
    return pdf; 
} 

ancora una volta, grazie mightymada - la vostra risposta è fantastico.

+4

ATTENZIONE: Pechkin (e TuesPechkin) sono superiori a iTextSharp in quasi tutti i modi (IMHO), tranne che non funzionano nei siti Web di Azure (forse molti ambienti di hosting condiviso?) –

+0

Pechkin è un wrapper intorno a wkhtmltopdf, che utilizza QT Webkit per * render * una pagina web in un pdf. In pratica è come dire "stampa su PDF" in Safari (un browser basato su Webkit). Che è un caso d'uso completamente diverso dalla creazione di un file PDF dal codice. E che è anche l'esatto opposto di quello che l'OP chiedeva. Quindi sono downvoting. –

3

Ha la capacità di convertire file HTML in pdf.

namespace richiesto per le conversioni sono:

using iTextSharp.text; 
using iTextSharp.text.pdf; 

e per la conversione e scaricare il file:

// Create a byte array that will eventually hold our final PDF 
Byte[] bytes; 

// Boilerplate iTextSharp setup here 

// Create a stream that we can write to, in this case a MemoryStream 
using (var ms = new MemoryStream()) 
{ 
    // Create an iTextSharp Document which is an abstraction of a PDF but **NOT** a PDF 
    using (var doc = new Document()) 
    { 
     // Create a writer that's bound to our PDF abstraction and our stream 
     using (var writer = PdfWriter.GetInstance(doc, ms)) 
     { 
      // Open the document for writing 
      doc.Open(); 

      string finalHtml = string.Empty; 

      // Read your html by database or file here and store it into finalHtml e.g. a string 
      // XMLWorker also reads from a TextReader and not directly from a string 
      using (var srHtml = new StringReader(finalHtml)) 
      { 
       // Parse the HTML 
       iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml); 
      } 

      doc.Close(); 
     } 
    } 

    // After all of the PDF "stuff" above is done and closed but **before** we 
    // close the MemoryStream, grab all of the active bytes from the stream 
    bytes = ms.ToArray(); 
} 

// Clear the response 
Response.Clear(); 
MemoryStream mstream = new MemoryStream(bytes); 

// Define response content type 
Response.ContentType = "application/pdf"; 

// Give the name of file of pdf and add in to header 
Response.AddHeader("content-disposition", "attachment;filename=invoice.pdf"); 
Response.Buffer = true; 
mstream.WriteTo(Response.OutputStream); 
Response.End(); 
+0

Che ne dici di .NET Core? – series0ne

1

Se si sta convertendo HTML in PDF sul lato server HTML è possibile utilizzare Rotativa:

Install-Package Rotativa 

Questo è basato su wkhtmltopdf ma ha un supporto CSS migliore rispetto a iTextSharp ha un d è molto semplice da integrare con MVC (che è principalmente usato) come si può semplicemente restituire la vista in pdf:

public ActionResult GetPdf() 
{ 
    //... 
    return new ViewAsPdf(model);// and you are done! 
}