基于iTextSharp的PDF文档操作
公司是跨境电商,需要和各种物流打交道,需要把东西交给物流,让他们发到世界各地。其中需要物流公司提供一个运单号,来追踪货物到达哪里?!
最近在和DHL物流公司(应该是个大公司)对接,取运单号的方式是调用对方提供的API,简单说,就是我们传一些发货地址和客户信息,要发的货物等,对方返回一个运单号和物流面单(就是我们淘宝快递上的面单)。过程呢,还是比较顺利的,经过一系列沟通,最终还是实现了功能
下面还是说说没有实现的功能,如果都实现了,也不用写这篇博客了。不足之处在于DHL提供的面单,没有提供要拣哪些货的面单。本来一个完整的面单,包括2部分:物流公司需要贴在包裹上的面单(物流面单)和我们自己发货部门要发哪些东西的面单(拣货面单),两部分组合在一起,发货部门才能正常的完成这个包裹的发货
好吧,终于要引入正题了,DHL公司将物流面单以pdf文件流的形式返回,就是我们可以保存成Pdf文件,这样就容易处理的多,我们自己的拣货面单,如果也可以保存至Pdf文件,这样就可以将这2个Pdf文件一块打印出来,这算是一个折中的解决方案。
首先,要将拣货数据(含图片)保存至Pdf文档。技术点如下
1, 将DataTable导出至Pdf
2, DataTable中包含图片,也要能导出
3, Pdf类库,字体的引入(居然需要引用字体的绝对路径,想不通)
下面分别讲解
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文件,合并成一个完整的发货面单
基于iTextSharp的PDF文档操作的更多相关文章
- 使用itextsharp创建PDF文档——图片集合
文档管理系统中 ,扫描模块将文档或证件扫描后.为了便于保存多个图片,拟将多个图片生成一个PDF文档进行保存. 这里我们就需要PDF生成工具了.你可以在这里下载.PDFCreator 主要使用了开源工具 ...
- 利用ItextSharp 生成PDF文档改进版
导入的ItextSharp.dll一定要是较高的版本 数据库表结构 生成的PDF样式 代码: namespace WebPDF { public partial class _Default : Sy ...
- iTextSharp生成pdf文档案例
1.using iTextSharp.text;using iTextSharp.text.pdf; 2.设置页面大小 iTextSharp.text.Rectangle pageSize = new ...
- 【转载】 C#工具类:使用iTextSharp操作PDF文档
iTextSharp是一个用于操作PDF文件的组件DLL程序,在C#程序中可以引用iTextSharp组件,用于开发与PDF文件相关的报表等功能,利用iTextSharp组件提供出来的方法接口,我们可 ...
- 【Win10 开发】读取PDF文档
关于用来读取PDF文档的内容的API,其实在Win8.1的时候就有,不过没关系,既咱们讨论的是10的UAP,连同8.1的内容也包括进去,所以老周无数次强调:把以前的内容学好了,就可以在不学习任何新知识 ...
- 操作PDF文档功能的相关开源项目探索——iTextSharp 和PDFBox
原文 操作PDF文档功能的相关开源项目探索——iTextSharp 和PDFBox 很久没自己写写心得日志与大家分享了,一方面是自己有点忙,一方面是自己有点懒,没有及时总结.因为实践是经验的来源,总结 ...
- 基于iTextSharp的PDF操作(PDF打印,PDF下载)
基于iTextSharp的PDF操作(PDF打印,PDF下载) 准备 1. iTextSharp的简介 iTextSharp是一个移植于java平台的iText项目,被封装成c#的组件来用于C#生成P ...
- .NET 操作PDF文档以及PDF文件打印摸索总结
关于生成 PDF 的操作,相信大家的在实际的工作过程中难免会碰到.以前我们通过生成 word 文档来进行文件的打印,但是由于太过依赖 office 软件,因此尝试能不能使用 PDF 进行文件打印. 在 ...
- java操作office和pdf文件java读取word,excel和pdf文档内容
在平常应用程序中,对office和pdf文档进行读取数据是比较常见的功能,尤其在很多web应用程序中.所以今天我们就简单来看一下Java对word.excel.pdf文件的读取.本篇博客只是讲解简单应 ...
随机推荐
- [板子]segTree
segTree 参考:http://www.cnblogs.com/TenosDoIt/p/3453089.html#c 初学者建议先参考上面“一步一步理解线段树”学习理论. 在这里Code分别为区间 ...
- webpack学习(一)
1.首先建立一个webpack项目,然后新建文件demo2,在demo2下新建src文件,index.html文件,初始化项目 (npm init --yes)得到package.json 2.全局安 ...
- code force 403B.B. The Meeting Place Cannot Be Changed
B. The Meeting Place Cannot Be Changed time limit per test 5 seconds memory limit per test 256 megab ...
- echarts2.2.7本地搭建
1.首先下载echarts2.2.7,解压到本地,解压后的目录如下: 2.在WebContent下建立一个名为build的目录,复制echarts2.2.7下面的build下面的dist目录到ecli ...
- scanf和cin性能的比较
我的实验机器配置是: 处理器:Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz 2.40GHz 随机访问存储器:4.00GB 操作系统:Windows10 集成开发环境 ...
- Linux系列教程(十九)——Linux文件系统管理之手工分区
上篇博客我们首先介绍了硬盘为什么要分区,以及Linux系统的几种分区类型,然后介绍了Linux系统几个常用的文件系统命令,最后讲解了挂载命令,并通过实例演示了如何挂载光盘和U盘. 本篇博客我们将介绍l ...
- 百度统计的JS脚本原理分析
首先,百度统计会要求我们在要统计的页面中嵌入一段js语句,类似如下: <script type="text/javascript">var _bdhmProtocol ...
- [转载] 一致性hash算法释义
转载自http://www.cnblogs.com/haippy/archive/2011/12/10/2282943.html 一致性Hash算法背景 一致性哈希算法在1997年由麻省理工学院的Ka ...
- RunLoop已入门?赶紧来应用一下
前言 对RunLoop还没有什么概念的同学请移步我的上一篇文章,传送门:RunLoop入门 看我就够了http://www.cnblogs.com/weiming4219/p/7879443.html ...
- 关于iOS GangSDK的使用,为App快速集成社群公会模块
手上有一个自己开发的小游戏,想加一个家族系统活跃下游戏的氛围,想到这块儿可能会有大量的工作需要自己做,就偷了个懒去网上搜罗了一波,结果惊奇的发现居然真的有类似的服务,并且还是免费的,所以决定入坑尝试一 ...