2016年5月13日 星期五

iTextSharp將HTML轉成PDF

之前就有用過iTextSharp將PDF合併,這次又需要用到它了。事情是這樣的,原本在專案裡使用的是AspPDF這個套件,把HTML的檔案轉成PDF做輸出給使用者下載,但最近客戶要換機,從Windows2003到Windows2012,本想說把套件裝一裝就可以了,但事情沒那麼簡單,這要追朔到當時接此專案的歷史,就不多說了,結論就是不能用。於是想到之前用過iTextSharp,印象中是免費又好用的套件,話不說就來看看如何實作~~
  1. 此專案當時是用.NET 3.5 vs2008 開發的,當然就沒有好用的NuGet,只好自己下載來安裝,這邊要下載兩個套件iTextSharpXmlWorker,基本上可以直接載最新版的,載下來後把參考加到專案中,
    如果可以使用NuGet就直接搜尋安裝即可。
  2. 這邊放上完整的程式碼,主要是抓取HTML的路徑把文字檔轉成byte產出PDF實體檔案
  3. public void print()
    {
        WebClient wc = New WebClient;
        wc.Encoding = Encoding.UTF8;
        string htmlText = wc.DownloadString("path");
        byte[] pdfFile = ConvertHtmlTextToPDF(htmlText);
        //將PDF產生出實體檔案
        File.WriteAllBytes("fileName", pdfFile);
    }
    
    public byte[] ConvertHtmlTextToPDF(string htmlText)
    {
        if (string.IsNullOrEmpty(htmlText)) {
            return null;
        }
        //
        htmlText = "" + htmlText + "
    "; MemoryStream outputStream = new MemoryStream(); byte[] data = Encoding.UTF8.GetBytes(htmlText); MemoryStream msInput = new MemoryStream(data); //A4橫印 //iTextSharp.text.Document doc = new iTextSharp.text.Document( new iTextSharp.text.Rectangle(288f, 144f), 10, 10, 10, 10); //doc.SetPageSize(iTextSharp.text.PageSize.A4.Rotate()); //A4直印 iTextSharp.text.Document doc = new iTextSharp.text.Document(); iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(doc, outputStream); iTextSharp.text.pdf.PdfDestination pdfDest = new iTextSharp.text.pdf.PdfDestination( iTextSharp.text.pdf.PdfDestination.XYZ, 0, doc.PageSize.Height, 1f); doc.Open(); iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml( writer, doc, msInput, null, Encoding.UTF8, new UnicodeFontFactory()); iTextSharp.text.pdf.PdfAction action = iTextSharp.text.pdf.PdfAction.GotoLocalPage(1, pdfDest, writer); writer.SetOpenAction(action); doc.Close(); msInput.Close(); outputStream.Close(); return outputStream.ToArray(); }
    支援Unicode的顯示
    using System;
    using System.IO;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    public class UnicodeFontFactory : iTextSharp.text.FontFactoryImp
    {
        //arial unicode MS是完整的unicode字型。
        private static string arialFontPath = 
            Path.Combine(
                Path.Combine(
                    Directory.GetParent(
                        Environment.GetFolderPath(Environment.SpecialFolder.System)).FullName, 
                        "Fonts"), "arialuni.ttf");
        //標楷體
        private static string chinesePath = 
            Path.Combine(
                Path.Combine(
                    Directory.GetParent(
                        Environment.GetFolderPath(Environment.SpecialFolder.System)).FullName, 
                        "Fonts"), "KAIU.TTF");
    
        public override iTextSharp.text.Font GetFont(string fontname, string encoding, 
            bool embedded, float size, int style, iTextSharp.text.BaseColor color, bool cached)
        {
            iTextSharp.text.pdf.BaseFont baseFont = iTextSharp.text.pdf.BaseFont.CreateFont(
                chinesePath, iTextSharp.text.pdf.BaseFont.IDENTITY_H, 
                iTextSharp.text.pdf.BaseFont.EMBEDDED);
            //
            return new iTextSharp.text.Font(baseFont, size, style, color);
        }
    }
    
    
  4. 至於在HTML檔案上有幾個要注意的是頁面寬度要設定成100%,如果設定死寬度很有可能會破版,另外這邊樣式的部分主要是支援CSS的,其他早期家在tag上的屬性都不再支援。

參考資料:https://dotblogs.com.tw/shadow/archive/2014/02/09/143891.aspx

1 則留言 :