公司是跨境電商,須要和各類物流打交道,須要把東西交給物流,讓他們發到世界各地。其中須要物流公司提供一個運單號,來追蹤貨物到達哪裏?!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文件,合併成一個完整的發貨面單