之前就有用過iTextSharp將PDF合併,這次又需要用到它了。事情是這樣的,原本在專案裡使用的是AspPDF這個套件,把HTML的檔案轉成PDF做輸出給使用者下載,但最近客戶要換機,從Windows2003到Windows2012,本想說把套件裝一裝就可以了,但事情沒那麼簡單,這要追朔到當時接此專案的歷史,就不多說了,結論就是不能用。於是想到之前用過iTextSharp,印象中是免費又好用的套件,話不說就來看看如何實作~~
- 此專案當時是用.NET 3.5 vs2008 開發的,當然就沒有好用的NuGet,只好自己下載來安裝,這邊要下載兩個套件iTextSharp及XmlWorker,基本上可以直接載最新版的,載下來後把參考加到專案中,
如果可以使用NuGet就直接搜尋安裝即可。
- 這邊放上完整的程式碼,主要是抓取HTML的路徑把文字檔轉成byte產出PDF實體檔案
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);
    }
}
- 至於在HTML檔案上有幾個要注意的是頁面寬度要設定成100%,如果設定死寬度很有可能會破版,另外這邊樣式的部分主要是支援CSS的,其他早期家在tag上的屬性都不再支援。
參考資料:
https://dotblogs.com.tw/shadow/archive/2014/02/09/143891.aspx