using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using CommonLib; using iTextSharp.text.pdf; using System.IO; using System.Drawing.Imaging; using System.Runtime.Serialization.Formatters.Binary; namespace Lskj.MyControl { /// /// Class PdfSignEx. /// public partial class PdfSignEx : UserControl { public PdfSignEx() { InitializeComponent(); } #region 公开变量 /// /// 当前保存签名的ID /// public int CurrentId; /// /// 源文件 /// public string TempletFilePath = string.Empty; /// /// 签名图片 /// public Image SignImage; /// /// 当前操作的位置 /// public PointF SignPoint; /// /// 签名载体 /// /// The pic box. public PictureBox PicBox { get { return this.pictureBox; } } /// /// 当前页 /// public int CurrentPageNo; /// /// 保存回调 /// public event EventHandler OnSaveCallBack; /// /// 删除回调 /// public event EventHandler OnDeleteCallBack; /// /// 另存为回调 /// public event EventHandler OnSaveAsCallBack; /// /// 打开回调 /// public event EventHandler OnOpenFileCallBack; #endregion #region 私有变量 /// /// 当前操作文件 /// private string _currentPdf; /// /// pdf文件合成存放目录 /// private string _fileDic = string.Empty; /// /// 上一次编辑的文件地址,保存失误后可以返回 /// private string _pdfHistory; /// /// 后台合成的PDf /// private string _pdfNew; /// /// 签名预制体集 /// private List _signBoxList; #endregion /// /// 说明: /// 创建人:姜棚 /// 创建日期:2018-06-08 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// public void ClosePDFViewer() { this.pdfDocument.Close(); } /// /// 说明:删除 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// public void Delete() { this.pictureBox.Visible = false; _signBoxList = _signBoxList.Where(o => o.PageNumber != this.pdfPageView.PageNumber).ToList(); } /// /// 说明:初始化pdf控件 /// 创建人:姜棚 /// 创建日期:2018-05-29 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// public void InitPdfEditor() { _signBoxList = new List(); this.pdfPageView.MouseWheel += new MouseEventHandler(OnMouseWheelClick); _fileDic = PubUtil.AbsolutelyPath + "PdfForder//"; if (!Directory.Exists(_fileDic)) { Directory.CreateDirectory(_fileDic); } DirectoryInfo dir = new DirectoryInfo(_fileDic); //初始化时清除掉文件 foreach (FileInfo f in dir.GetFiles("*.pdf")) { f.Delete(); } } /// /// 说明:初始在源文件上描点 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// public void InitPdfPage(DataTable dt) { this.CurrentId = 0; if (dt == null || dt.Rows.Count == 0) { this._pdfHistory = this._currentPdf = this.TempletFilePath; if (string.IsNullOrEmpty(this.TempletFilePath)) { MessageBox.Show("不存在源文件"); } } else { this._pdfHistory = this._currentPdf = _fileDic + Guid.NewGuid() + ".pdf"; using (Stream outputPdfStream = new FileStream(this._currentPdf, FileMode.Create, FileAccess.Write, FileShare.None)) { PdfReader reader = new PdfReader(this.TempletFilePath); PdfStamper stamper = new PdfStamper(reader, outputPdfStream); foreach (DataRow row in dt.Rows) { Image pic = Image.FromStream(new MemoryStream((byte[])row["Image"]), true); //ms.Close(); iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(pic, pic.RawFormat); // 由于不清楚表结构暂时没定义模型 PointF point = new PointF(float.Parse(row["ImageX"] + ""), float.Parse(row["ImageY"] + "")); AddImageToPdf(image, Convert.ToInt32(row["Page"] + ""), point, stamper); } stamper.Close(); reader.Close(); } } this.pdfDocument.Load(this._currentPdf); this.pdfPageView.PageNumber = this.CurrentPageNo; } /// /// 说明:保存 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// public void Save() { if (this._pdfNew == null) return; //签名容器状态代表是否可进行保存 this._currentPdf = this._pdfNew; this._signBoxList.Clear(); this.pictureBox.Visible = false; this.pdfDocument.Load(this._currentPdf); //加载到保存前的页码位置 this.pdfPageView.PageNumber = this.CurrentPageNo; } /// /// 说明:另存为 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// public bool SaveAs() { this.Save(); string fileName = string.Empty; bool saveState = false; using (SaveFileDialog saveFileDialog = new SaveFileDialog()) { saveFileDialog.Title = "另存为"; saveFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); saveFileDialog.Filter = "pdf(*.pdf)|*.pdf"; saveFileDialog.AddExtension = true; if (saveFileDialog.ShowDialog() == DialogResult.OK) { fileName = saveFileDialog.FileName; this.pdfDocument.Save(fileName); saveState = true; } else { //另存操作失误,取消另存时候,加载到保存前状态 this._currentPdf = this._pdfHistory; this.pdfDocument.Load(this._currentPdf); this.pdfPageView.PageNumber = this.CurrentPageNo; } return saveState; } } /// /// 说明:添加图片到Pdf /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// 图片地址 /// 页码 /// 坐标点 /// stamper /// 是否计算,由于初始绘制点是计算好的不用计算. private void AddImageToPdf(iTextSharp.text.Image image, int pageNo, PointF point, PdfStamper stamper, bool isCalc = false) { PdfContentByte pdfContentByte = stamper.GetOverContent(Convert.ToInt32(pageNo + 1)); int percent = GetPercentSize(image.Height, image.Width); image.ScalePercent(percent); if (isCalc) { this.SignPoint= point = new PointF(point.X, float.Parse(point.Y - image.Height * percent * 0.01 / 2 + "")); } image.SetAbsolutePosition(point.X, point.Y); pdfContentByte.AddImage(image); } /// /// 说明:根据比例缩放图片 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// 高度 /// 宽度 /// System.Int32. private int GetPercentSize(float height, float width) { float percent = height / width * 100; return Convert.ToInt32(Math.Round(percent)); } /// /// 说明:打开本地文件(先屏蔽) /// 创建人:姜棚 /// 创建日期:2018-05-28 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// System.String. //private string OpenLocalFile() //{ // string fileName = string.Empty; // OpenFileDialog openFileDialog = new OpenFileDialog(); // openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); // openFileDialog.Filter = "(*.pdf)|*.pdf"; // openFileDialog.RestoreDirectory = true; // openFileDialog.FilterIndex = 1; // if (openFileDialog.ShowDialog() == DialogResult.OK) // { // TempletFilePath = fileName = openFileDialog.FileName; // } // return fileName; //} /// /// 说明:画签名 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// private void DrawSignBox(Point point) { pictureBox.Visible = true; pictureBox.Width = SignImage.Width; pictureBox.Height = SignImage.Height; pictureBox.Image = SignImage; pictureBox.Location = new Point(point.X, point.Y - this.pictureBox.Height / 2); } /// /// 说明:记录保存的签名 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// private void SaveSignBox(Point point) { //先移除本页原有的点 this._signBoxList.Remove(_signBoxList.FirstOrDefault(o => o.PageNumber == this.CurrentPageNo)); SignBox signBox = new SignBox(); signBox.PageNumber = this.CurrentPageNo; signBox.PointObj = point; this._signBoxList.Add(signBox); } /// /// 说明:找到记录的sign坐标并画 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// private void FindSignBox() { SignBox sign = _signBoxList.FirstOrDefault(o => o.PageNumber == this.pdfPageView.PageNumber); if (sign != null) { DrawSignBox(sign.PointObj); } else { pictureBox.Visible = false; } } #region 事件部分 /// /// 说明:清除签名点 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The source of the event. /// The instance containing the event data. void OnDeleteClick(object sender, EventArgs e) { if (OnDeleteCallBack != null) OnDeleteCallBack(null, null); } /// /// 说明:鼠标滑轮滚动事件 /// 创建人:姜棚 /// 创建日期:2018-05-29 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The sender. /// The instance containing the event data. void OnMouseWheelClick(object sender, MouseEventArgs e) { //向前滑 if (e.Delta > 0) { OnPageUpClick(null, null); } else { OnPageNextClick(null, null); } } /// /// 说明:点击pdf /// 创建人:姜棚 /// 创建日期:2018-06-04 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The sender. /// The instance containing the event data. void OnPageClick(object sender, O2S.Components.PDFView4NET.PageClickEventArgs e) { //初始化签名键值 this.CurrentId = 0; this.CurrentPageNo = this.pdfPageView.PageNumber; PdfReader reader = new PdfReader(this._currentPdf); //记录上次操作文件,操作失误能返回 this._pdfHistory = this._currentPdf; //合成的文件地址 this._pdfNew = _fileDic + Guid.NewGuid() + ".pdf"; using (Stream outPutPdfStream = new FileStream(_pdfNew, FileMode.Create, FileAccess.Write, FileShare.None)) { iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(SignImage, SignImage.RawFormat); PdfStamper stamper = new PdfStamper(reader, outPutPdfStream); PointF point = new PointF(float.Parse(e.PDFPoint.X + ""), float.Parse(e.PDFPoint.Y + "")); this.AddImageToPdf(image, this.CurrentPageNo, point, stamper, true); stamper.Close(); } reader.Close(); DrawSignBox(e.ControlPoint); //将打的点记录下来 SaveSignBox(e.ControlPoint); } /// /// 说明:上一页 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The source of the event. /// The instance containing the event data. void OnPageUpClick(object sender, EventArgs e) { if (this.pdfPageView.PageNumber > 0) { this.pdfPageView.PageNumber--; FindSignBox(); } } /// /// 说明:下一页 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The source of the event. /// The instance containing the event data. void OnPageNextClick(object sender, EventArgs e) { if (this.pdfPageView.PageNumber < this.pdfDocument.PageCount - 1) { this.pdfPageView.PageNumber++; FindSignBox(); } } /// /// 说明:保存事件 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The source of the event. /// The instance containing the event data. void OnSaveClick(object sender, EventArgs e) { if (OnSaveCallBack != null) OnSaveCallBack(null, null); } /// /// 说明:另存事件 /// 创建人:姜棚 /// 创建日期:2018-05-30 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The source of the event. /// The instance containing the event data. void OnSaveAsClick(object sender, EventArgs e) { if (OnSaveAsCallBack != null) OnSaveAsCallBack(null, null); } #endregion class SignBox { /// /// 页码 /// /// The page number. public int PageNumber { get; set; } /// /// 坐标 /// /// The point. public Point PointObj { get; set; } } } }