基於iTextSharp的PDF文檔操做

  公司是跨境電商,須要和各類物流打交道,須要把東西交給物流,讓他們發到世界各地。其中須要物流公司提供一個運單號,來追蹤貨物到達哪裏?!html

  最近在和DHL物流公司(應該是個大公司)對接,取運單號的方式是調用對方提供的API,簡單說,就是咱們傳一些發貨地址和客戶信息,要發的貨物等,對方返回一個運單號和物流面單(就是咱們淘寶快遞上的面單)。過程呢,仍是比較順利的,通過一系列溝通,最終仍是實現了功能ide

  下面仍是說說沒有實現的功能,若是都實現了,也不用寫這篇博客了。不足之處在於DHL提供的面單,沒有提供要揀哪些貨的面單。原本一個完整的面單,包括2部分:物流公司須要貼在包裹上的面單(物流面單)和咱們本身發貨部門要發哪些東西的面單(揀貨面單),兩部分組合在一塊兒,發貨部門才能正常的完成這個包裹的發貨字體

  好吧,終於要引入正題了,DHL公司將物流面單以pdf文件流的形式返回,就是咱們能夠保存成Pdf文件,這樣就容易處理的多,咱們本身的揀貨面單,若是也能夠保存至Pdf文件,這樣就能夠將這2個Pdf文件一塊打印出來,這算是一個折中的解決方案。.net

  首先,要將揀貨數據(含圖片)保存至Pdf文檔。技術點以下htm

    1, 將DataTable導出至Pdf對象

    2, DataTable中包含圖片,也要能導出blog

    3, Pdf類庫,字體的引入(竟然須要引用字體的絕對路徑,想不通)圖片

  下面分別講解ip

    1, 這點就是直接建立iTextSharp中的PdfDataTable對象,直接映射便可。代碼以下:文檔

private static pdfText.pdf.PdfPTable CreatePdfPTableToPickupLabel(List<TradeDetailModel> listDetail, iTextSharp.text.Font font)
{
    pdfText.pdf.PdfPTable pdtTable = new pdfText.pdf.PdfPTable(5);
    pdtTable.WidthPercentage = 95;      //佔寬度百分比:95%(這句很關鍵,做用是撐滿整個面單)

    int[] colWidth = { 2, 4, 2, 2, 2 }; //設置列寬比例
    pdtTable.SetWidths(colWidth);

    //此處,先插入首行,即標題
    pdtTable.AddCell(new iTextSharp.text.Phrase("圖片", font));
    pdtTable.AddCell(new iTextSharp.text.Phrase("基本信息", font));
    pdtTable.AddCell(new iTextSharp.text.Phrase("單價", font));
    pdtTable.AddCell(new iTextSharp.text.Phrase("數量", font));
    pdtTable.AddCell(new iTextSharp.text.Phrase("備註", font));

    //再插入真實揀貨數據
    int rowCount = listDetail.Count;
    for (int i = 0; i < rowCount; i++)
    {
        TradeDetailModel modelDetail = listDetail[i];

        iTextSharp.text.Image image = PdfUtil.CreatePdfImage(modelDetail.ProductImageBytes);
        pdtTable.AddCell(image);
        pdtTable.AddCell(new iTextSharp.text.Phrase(modelDetail.ProductBase, font));
        pdtTable.AddCell(new iTextSharp.text.Phrase(modelDetail.Price.ToString() + Environment.NewLine + modelDetail.ProductID, font));
        pdtTable.AddCell(new iTextSharp.text.Phrase(modelDetail.Number.ToString() + Environment.NewLine + modelDetail.ProductSpec, font));
        pdtTable.AddCell(new iTextSharp.text.Phrase(modelDetail.Remark, font));
    }

    return pdtTable;
}

    2, 這點要先生成iTextSharp中Image對象才能夠,而後再隨生成PdfDataTable中,將Image對象插入單元格(注意:圖片尺寸須要定義好)。代碼以下:

/// <summary>
/// 建立Pdf所需圖像
/// </summary>
/// <param name="imageBytes"></param>
/// <param name="widthS"></param>
/// <param name="heightS"></param>
/// <returns></returns>
private static iTextSharp.text.Image CreatePdfImage(byte[] imageBytes, float widthS = 60f, float heightS = 60f)
{
    iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imageBytes);

    //圖片大小要求統一80x80,需根據實際圖片        
    float perW = (float)Math.Round(widthS / image.Width, 2);
    float perH = (float)Math.Round(heightS / image.Height, 2);
    image.ScalePercent(perW * 100, perH * 100);

    //設置Dpi值,可以清晰些
    image.SetDpi(124, 124);

    return image;
}  

    3, 建立字體

/// <summary>
/// 建立Pdf所需字體
/// </summary>
/// <returns></returns>
public static iTextSharp.text.Font CreatePdfFont(float fontSize = 16F)
{
    //黑體
    string fontPath = @"C:\Windows\Fonts\simhei.ttf";

    iTextSharp.text.pdf.BaseFont baseFont = iTextSharp.text.pdf.BaseFont.CreateFont(fontPath,
        iTextSharp.text.pdf.BaseFont.IDENTITY_H,
        iTextSharp.text.pdf.BaseFont.NOT_EMBEDDED);
    iTextSharp.text.Font font = new iTextSharp.text.Font(baseFont, fontSize);

    return font;
}

    下面是調用的代碼,僅供參考。注:返回的Pdf文件的絕對路徑,用於後續打印

/// <summary>
/// 生成揀貨標籤pdf文件
/// </summary>
/// <param name="modelTrade"></param>
/// <param name="dhlLabelFolderName"></param>
/// <returns></returns>
public static string CreatePickupLabel(TradeModel modelTrade,string dhlLabelFolderName)
{
    //參考地址
    //https://www.cnblogs.com/yangy1989/p/5300304.html
    //http://blog.csdn.net/lideyuans/article/details/51536676 (設置圖片百分比)

    //組裝,待生成的pdf文件完整路徑
    string logisticsNo = modelTrade.R;
    string pdfFileName = dhlLabelFolderName + logisticsNo + "_Label.pdf";

    FileStream fs = new FileStream(pdfFileName, FileMode.Create);
    pdfText.Rectangle rect = new pdfText.Rectangle(0f, 0f, 1000f, 1000f);
    pdfText.Document document = new pdfText.Document(rect, 5f, 5f, 5f, 5f);

    //建立字體
    iTextSharp.text.Font font = PdfUtil.CreatePdfFont(34F);

    pdfText.pdf.PdfWriter pdfWriter = pdfText.pdf.PdfWriter.GetInstance(document, fs);
    document.Open();

    //增長揀貨單品列表
    pdfText.pdf.PdfPTable pdfpTable = PdfUtil.CreatePdfPTableToPickupLabel(modelTrade.Details, font);
    document.Add(pdfpTable);

    //增長品名備註            
    pdfText.Paragraph pgraph1 = new pdfText.Paragraph(modelTrade.ItemsDescription, font);
    document.Add(pgraph1);

    //增長:發貨期限
    font.Color = pdfText.BaseColor.RED;
    pdfText.Paragraph pgraph2 = new pdfText.Paragraph(modelTrade.ShipLimitTimeText, font);
    document.Add(pgraph2);

    document.Close();
    fs.Close();

    return pdfFileName;
}

  

  再將這2個文件,經過C#代碼連續打印出來。支持連續打印多個Pdf文件

//直接調用cmd命令,實現直接打印
foreach (string printFile in listPrintFile)
{
    Process proc = new Process();
    proc.StartInfo.CreateNoWindow = false;
    proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    proc.StartInfo.UseShellExecute = true;
    proc.StartInfo.FileName = printFile;
    proc.StartInfo.Verb = "print";
    proc.Start();
    proc.Close();
}

  

  好了,最後的最後,看看效果圖吧。前2聯是DHL返回的Pdf文件,第3聯是我本地生成的Pdf文件,合併成一個完整的發貨面單

相關文章
相關標籤/搜索