Programing

iTextSharp를 사용하여 HTML을 PDF로 변환하는 방법

lottogame 2020. 11. 20. 08:26
반응형

iTextSharp를 사용하여 HTML을 PDF로 변환하는 방법


iTextSharp를 사용하여 아래 HTML을 PDF로 변환하고 싶지만 어디서부터 시작해야할지 모르겠습니다.

<style>
.headline{font-size:200%}
</style>
<p>
  This <em>is </em>
  <span class="headline" style="text-decoration: underline;">some</span>
  <strong>sample<em> text</em></strong>
  <span style="color: red;">!!!</span>
</p>

첫째, HTML과 PDF는 거의 동시에 만들어졌지만 관련이 없습니다. HTML은 단락 및 표와 같은 더 높은 수준의 정보를 전달하기위한 것입니다. 이를 제어하는 ​​방법이 있지만 이러한 상위 수준 개념을 그리는 것은 궁극적으로 브라우저에 달려 있습니다. PDF를 전달하기위한 것입니다 문서 및 문서가 있어야 그들이 렌더링되는 곳마다 같은 "모양".

HTML 문서에는 너비가 100 % 인 단락이있을 수 있으며 모니터 너비에 따라 2 줄 또는 10 줄이 필요할 수 있으며 인쇄 할 때 7 줄이 될 수 있으며 휴대폰에서 볼 때 20 줄을 타십시오. 그러나 PDF 파일 은 렌더링 장치와 독립적 이어야 하므로 화면 크기에 관계없이 항상 정확히 동일하게 렌더링 해야합니다 .

필수 사항 때문에 PDF는 "표"또는 "단락"과 같은 추상적 인 것을 지원하지 않습니다. PDF가 지원하는 세 가지 기본 사항은 텍스트, 선 / 모양 및 이미지입니다. (주석 및 동영상과 같은 다른 것들이 있지만 여기서는 간단하게 유지하려고합니다.) PDF에서 "여기에 단락이 있습니다. 브라우저가 귀하의 작업을 수행합니다!"라고 말하지 않습니다. 대신 "이 정확한 글꼴을 사용하여 정확한 X, Y 위치에이 텍스트를 그리고 걱정하지 마십시오. 이전에 텍스트 너비를 계산 했으므로이 줄에 모두 맞을 것입니다."라고 말합니다. 또한 "여기에 테이블이 있습니다"라고 말하지 않고 대신 "이 텍스트를이 정확한 위치에 그린 다음 내가 원하는 다른 정확한 위치에 직사각형을 그립니다."라고 말합니다.

둘째, iText 및 iTextSharp는 HTML 및 CSS를 구문 분석합니다. 그게 다야. ASP.Net, MVC, Razor, Struts, Spring 등은 모두 HTML 프레임 워크이지만 iText / iTextSharp는 100 % 인식하지 못합니다. 모든 프레임 워크 별 추상화 인 DataGridViews, Repeater, Templates, Views 등과 동일합니다. 선택한 프레임 워크에서 HTML을 가져 오는 것은 사용자의 책임이며 iText는 도움이되지 않습니다. 예외가 발생 The document has no pages하거나 "iText가 내 HTML을 구문 분석하지 않습니다" 라고 생각하면 실제로 HTML 이 없다는 것이 거의 확실합니다 .

셋째, 수년 동안 사용되어 온 내장 클래스는 ( Java / .Net ) HTMLWorker으로 대체되었습니다 . CSS 파일을 지원하지 않고 가장 기본적인 CSS 속성에 대한 지원 만 제한 하고 특정 태그에서 실제로 중단 되는 작업 이 전혀 없습니다 . 당신이 표시되지 않는 경우 이 파일에 HTML 속성 또는 CSS 속성과 값을 그때는 아마 지원하지 않습니다 . 더 때로는 복잡하지만, 그 합병증도 할 수 는 있도록 더욱 확장 .XMLWorkerHTMLWorkerHTMLWorkerXMLWorker

다음은 HTML 태그를 작업중인 문서에 자동으로 추가되는 iText 추상화로 구문 분석하는 방법을 보여주는 C # 코드입니다. C #과 Java는 매우 유사하므로 비교적 쉽게 변환 할 수 있습니다. 예제 # 1은 내장을 사용 HTMLWorker하여 HTML 문자열을 구문 분석합니다. 인라인 스타일 만 지원되므로 class="headline"무시되지만 나머지는 실제로 작동합니다. 예제 # 2는 XMLWorker대신 사용 하는 것을 제외하고 첫 번째와 동일 합니다. 예제 # 3은 간단한 CSS 예제도 파싱합니다.

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

            //Our sample HTML and CSS
            var example_html = @"<p>This <em>is </em><span class=""headline"" style=""text-decoration: underline;"">some</span> <strong>sample <em> text</em></strong><span style=""color: red;"">!!!</span></p>";
            var example_css = @".headline{font-size:200%}";

            /**************************************************
             * Example #1                                     *
             *                                                *
             * Use the built-in HTMLWorker to parse the HTML. *
             * Only inline CSS is supported.                  *
             * ************************************************/

            //Create a new HTMLWorker bound to our document
            using (var htmlWorker = new iTextSharp.text.html.simpleparser.HTMLWorker(doc)) {

                //HTMLWorker doesn't read a string directly but instead needs a TextReader (which StringReader subclasses)
                using (var sr = new StringReader(example_html)) {

                    //Parse the HTML
                    htmlWorker.Parse(sr);
                }
            }

            /**************************************************
             * Example #2                                     *
             *                                                *
             * Use the XMLWorker to parse the HTML.           *
             * Only inline CSS and absolutely linked          *
             * CSS is supported                               *
             * ************************************************/

            //XMLWorker also reads from a TextReader and not directly from a string
            using (var srHtml = new StringReader(example_html)) {

                //Parse the HTML
                iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml);
            }

            /**************************************************
             * Example #3                                     *
             *                                                *
             * Use the XMLWorker to parse HTML and CSS        *
             * ************************************************/

            //In order to read CSS as a string we need to switch to a different constructor
            //that takes Streams instead of TextReaders.
            //Below we convert the strings into UTF8 byte array and wrap those in MemoryStreams
            using (var msCss = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_css))) {
                using (var msHtml = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_html))) {

                    //Parse the HTML
                    iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHtml, msCss);
                }
            }


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

//Now we just need to do something with those bytes.
//Here I'm writing them to disk but if you were in ASP.Net you might Response.BinaryWrite() them.
//You could also write the bytes to a database in a varbinary() column (but please don't) or you
//could pass them to another function for further PDF processing.
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");
System.IO.File.WriteAllBytes(testFile, bytes);

2017 년 업데이트

HTML에서 PDF 로의 요구에 대한 좋은 소식이 있습니다. 으로 이 대답했다 , W3C의 표준 CSS - 휴식 - 3 문제를 해결할 것입니다 ... 그것은 테스트 후, 올해 최종 권고로 전환 할 계획이있는 후보 추천입니다.

그다지 표준이 아니기 때문에 print-css.rocks표시된 대로 C # 용 플러그인이있는 솔루션이 있습니다 .


@ 크리스 하스 사용하는 방법을 잘 설명하고있다 itextSharp변환하는 데 HTMLPDF매우 도움이,
내 추가 기능은
사용하여 HtmlTextWriter내부 I 넣어 HTML 태그를 HTML내가 사용하지 않고 원하는대로 내가 내 PDF를 가지고 테이블 + 인라인 CSS XMLWorker.
편집 : 샘플 코드 추가 :
ASPX 페이지 :

<asp:Panel runat="server" ID="PendingOrdersPanel">
 <!-- to be shown on PDF-->
 <table style="border-spacing: 0;border-collapse: collapse;width:100%;display:none;" >
 <tr><td><img src="abc.com/webimages/logo1.png" style="display: none;" width="230" /></td></tr>
<tr style="line-height:10px;height:10px;"><td style="display:none;font-size:9px;color:#10466E;padding:0px;text-align:right;">blablabla.</td></tr>
 <tr style="line-height:10px;height:10px;"><td style="display:none;font-size:9px;color:#10466E;padding:0px;text-align:right;">blablabla.</td></tr>
 <tr style="line-height:10px;height:10px;"><td style="display:none;font-size:9px;color:#10466E;padding:0px;text-align:right;">blablabla</td></tr>
<tr style="line-height:10px;height:10px;"><td style="display:none;font-size:9px;color:#10466E;padding:0px;text-align:right;">blablabla</td></tr>
<tr style="line-height:10px;height:10px;"><td style="display:none;font-size:11px;color:#10466E;padding:0px;text-align:center;"><i>blablabla</i> Pending orders report<br /></td></tr>
 </table>
<asp:GridView runat="server" ID="PendingOrdersGV" RowStyle-Wrap="false" AllowPaging="true" PageSize="10" Width="100%" CssClass="Grid" AlternatingRowStyle-CssClass="alt" AutoGenerateColumns="false"
   PagerStyle-CssClass="pgr" HeaderStyle-ForeColor="White" PagerStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" RowStyle-HorizontalAlign="Center" DataKeyNames="Document#" 
      OnPageIndexChanging="PendingOrdersGV_PageIndexChanging" OnRowDataBound="PendingOrdersGV_RowDataBound" OnRowCommand="PendingOrdersGV_RowCommand">
   <EmptyDataTemplate><div style="text-align:center;">no records found</div></EmptyDataTemplate>
    <Columns>                                           
     <asp:ButtonField CommandName="PendingOrders_Details" DataTextField="Document#" HeaderText="Document #" SortExpression="Document#" ItemStyle-ForeColor="Black" ItemStyle-Font-Underline="true"/>
      <asp:BoundField DataField="Order#" HeaderText="order #" SortExpression="Order#"/>
     <asp:BoundField DataField="Order Date" HeaderText="Order Date" SortExpression="Order Date" DataFormatString="{0:d}"></asp:BoundField> 
    <asp:BoundField DataField="Status" HeaderText="Status" SortExpression="Status"></asp:BoundField>
    <asp:BoundField DataField="Amount" HeaderText="Amount" SortExpression="Amount" DataFormatString="{0:C2}"></asp:BoundField> 
   </Columns>
    </asp:GridView>
</asp:Panel>

C # 코드 :

protected void PendingOrdersPDF_Click(object sender, EventArgs e)
{
    if (PendingOrdersGV.Rows.Count > 0)
    {
        //to allow paging=false & change style.
        PendingOrdersGV.HeaderStyle.ForeColor = System.Drawing.Color.Black;
        PendingOrdersGV.BorderColor = Color.Gray;
        PendingOrdersGV.Font.Name = "Tahoma";
        PendingOrdersGV.DataSource = clsBP.get_PendingOrders(lbl_BP_Id.Text);
        PendingOrdersGV.AllowPaging = false;
        PendingOrdersGV.Columns[0].Visible = false; //export won't work if there's a link in the gridview
        PendingOrdersGV.DataBind();

        //to PDF code --Sam
        string attachment = "attachment; filename=report.pdf";
        Response.ClearContent();
        Response.AddHeader("content-disposition", attachment);
        Response.ContentType = "application/pdf";
        StringWriter stw = new StringWriter();
        HtmlTextWriter htextw = new HtmlTextWriter(stw);
        htextw.AddStyleAttribute("font-size", "8pt");
        htextw.AddStyleAttribute("color", "Grey");

        PendingOrdersPanel.RenderControl(htextw); //Name of the Panel
        Document document = new Document();
        document = new Document(PageSize.A4, 5, 5, 15, 5);
        FontFactory.GetFont("Tahoma", 50, iTextSharp.text.BaseColor.BLUE);
        PdfWriter.GetInstance(document, Response.OutputStream);
        document.Open();

        StringReader str = new StringReader(stw.ToString());
        HTMLWorker htmlworker = new HTMLWorker(document);
        htmlworker.Parse(str);

        document.Close();
        Response.Write(document);
    }
}

물론 cs 파일에 iTextSharp Refrences 포함

using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html.simpleparser;
using iTextSharp.tool.xml;

도움이 되었기를 바랍니다!
감사합니다


2018 년부터 iText7 (이전 iTextSharp 라이브러리의 다음 반복)과 HTML to PDF 패키지도 제공됩니다 : itext7.pdfhtml

사용법은 간단합니다.

HtmlConverter.ConvertToPdf(
    new FileInfo(@"Path\to\Html\File.html"),
    new FileInfo(@"Path\to\Pdf\File.pdf")
);

메서드에는 더 많은 오버로드가 있습니다.

업데이트 : iText * 제품군에는 이중 라이센스 모델이 있습니다 . 오픈 소스는 무료이고 상업용은 유료입니다.


다음 코드를 사용하여 PDF를 만듭니다.

protected void CreatePDF(Stream stream)
        {
            using (var document = new Document(PageSize.A4, 40, 40, 40, 30))
            {
                var writer = PdfWriter.GetInstance(document, stream);
                writer.PageEvent = new ITextEvents();
                document.Open();

                // instantiate custom tag processor and add to `HtmlPipelineContext`.
                var tagProcessorFactory = Tags.GetHtmlTagProcessorFactory();
                tagProcessorFactory.AddProcessor(
                    new TableProcessor(),
                    new string[] { HTML.Tag.TABLE }
                );

                //Register Fonts.
                XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
                fontProvider.Register(HttpContext.Current.Server.MapPath("~/Content/Fonts/GothamRounded-Medium.ttf"), "Gotham Rounded Medium");
                CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);

                var htmlPipelineContext = new HtmlPipelineContext(cssAppliers);
                htmlPipelineContext.SetTagFactory(tagProcessorFactory);

                var pdfWriterPipeline = new PdfWriterPipeline(document, writer);
                var htmlPipeline = new HtmlPipeline(htmlPipelineContext, pdfWriterPipeline);

                // get an ICssResolver and add the custom CSS
                var cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true);
                cssResolver.AddCss(CSSSource, "utf-8", true);
                var cssResolverPipeline = new CssResolverPipeline(
                    cssResolver, htmlPipeline
                );

                var worker = new XMLWorker(cssResolverPipeline, true);
                var parser = new XMLParser(worker);
                using (var stringReader = new StringReader(HTMLSource))
                {
                    parser.Parse(stringReader);
                    document.Close();
                    HttpContext.Current.Response.ContentType = "application /pdf";
                    if (base.View)
                        HttpContext.Current.Response.AddHeader("content-disposition", "inline;filename=\"" + OutputFileName + ".pdf\"");
                    else
                        HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=\"" + OutputFileName + ".pdf\"");
                    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
                    HttpContext.Current.Response.WriteFile(OutputPath);
                    HttpContext.Current.Response.End();
                }
            }
        }

여기 제가 가이드로 사용한 링크가 있습니다. 도움이 되었기를 바랍니다!

ITextSharp를 사용하여 HTML을 PDF로 변환

protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            string strHtml = string.Empty;
            //HTML File path -http://aspnettutorialonline.blogspot.com/
            string htmlFileName = Server.MapPath("~") + "\\files\\" + "ConvertHTMLToPDF.htm";
            //pdf file path. -http://aspnettutorialonline.blogspot.com/
            string pdfFileName = Request.PhysicalApplicationPath + "\\files\\" + "ConvertHTMLToPDF.pdf";

            //reading html code from html file
            FileStream fsHTMLDocument = new FileStream(htmlFileName, FileMode.Open, FileAccess.Read);
            StreamReader srHTMLDocument = new StreamReader(fsHTMLDocument);
            strHtml = srHTMLDocument.ReadToEnd();
            srHTMLDocument.Close();

            strHtml = strHtml.Replace("\r\n", "");
            strHtml = strHtml.Replace("\0", "");

            CreatePDFFromHTMLFile(strHtml, pdfFileName);

            Response.Write("pdf creation successfully with password -http://aspnettutorialonline.blogspot.com/");
        }
        catch (Exception ex)
        {
            Response.Write(ex.Message);
        }
    }
    public void CreatePDFFromHTMLFile(string HtmlStream, string FileName)
    {
        try
        {
            object TargetFile = FileName;
            string ModifiedFileName = string.Empty;
            string FinalFileName = string.Empty;

            /* To add a Password to PDF -http://aspnettutorialonline.blogspot.com/ */
            TestPDF.HtmlToPdfBuilder builder = new TestPDF.HtmlToPdfBuilder(iTextSharp.text.PageSize.A4);
            TestPDF.HtmlPdfPage first = builder.AddPage();
            first.AppendHtml(HtmlStream);
            byte[] file = builder.RenderPdf();
            File.WriteAllBytes(TargetFile.ToString(), file);

            iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(TargetFile.ToString());
            ModifiedFileName = TargetFile.ToString();
            ModifiedFileName = ModifiedFileName.Insert(ModifiedFileName.Length - 4, "1");

            string password = "password";
            iTextSharp.text.pdf.PdfEncryptor.Encrypt(reader, new FileStream(ModifiedFileName, FileMode.Append), iTextSharp.text.pdf.PdfWriter.STRENGTH128BITS, password, "", iTextSharp.text.pdf.PdfWriter.AllowPrinting);
            //http://aspnettutorialonline.blogspot.com/
            reader.Close();
            if (File.Exists(TargetFile.ToString()))
                File.Delete(TargetFile.ToString());
            FinalFileName = ModifiedFileName.Remove(ModifiedFileName.Length - 5, 1);
            File.Copy(ModifiedFileName, FinalFileName);
            if (File.Exists(ModifiedFileName))
                File.Delete(ModifiedFileName);

        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

샘플 파일을 다운로드 할 수 있습니다. 그냥 배치 html당신이에서 변환 할 files폴더 및 실행됩니다. pdf 파일이 자동으로 생성되어 동일한 폴더에 저장됩니다. 그러나 귀하의 경우에는 htmlFileName변수에 html 경로를 지정할 수 있습니다 .

참고 URL : https://stackoverflow.com/questions/25164257/how-to-convert-html-to-pdf-using-itextsharp

반응형