using iTextSharp.text; using iTextSharp.text.pdf; using System; using System.IO; namespace ReportEngine { public class ReportCanvas : PdfPageEventHelper { PdfContentByte _dcContent; PdfTemplate _tFooterPageTotal; readonly ReportCanvasOptions _rpoOptions; public ReportCanvas(ReportCanvasOptions i_rpoOptions) { _rpoOptions = i_rpoOptions; } public override void OnEndPage(PdfWriter writer, Document document) { // 頁尾頁數設定 if (_rpoOptions.IsShowPageNumber) { var baseCenter = _rpoOptions.PageSize.Right / 2; var pageBottom = (document.BottomMargin - _rpoOptions.FontSize) / 2 + 5; var pageCenter = baseCenter; // 頁碼偏移 var pageN = writer.PageNumber; string pageText = $"{pageN}/" ; var textWidth = _rpoOptions.BaseFont.GetWidthPoint(pageText, _rpoOptions.FontSize); _dcContent.SetFontAndSize(_rpoOptions.BaseFont, _rpoOptions.FontSize); // 預設文字大小 _dcContent.BeginText(); _dcContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, pageText, pageCenter- textWidth, pageBottom, 0); _dcContent.EndText(); _dcContent.AddTemplate(_tFooterPageTotal, pageCenter, pageBottom - 1); } base.OnEndPage(writer, document); } public override void OnOpenDocument(PdfWriter writer, Document document) { base.OnOpenDocument(writer, document); _dcContent = writer.DirectContent; if (_rpoOptions.IsShowPageNumber) { _tFooterPageTotal = _dcContent.CreateTemplate(50, 50); } } public string Paint(Func i_fPainting, [System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0, [System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "", [System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "") { string sMsg; try { do { Document doc = new Document(_rpoOptions.PageSize, _rpoOptions.PageMarginLeft, _rpoOptions.PageMarginRight, _rpoOptions.PageMarginHeader, _rpoOptions.PageMarginFooter); MemoryStream memoryStream = new MemoryStream(); PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream); writer.CloseStream = false; if (_rpoOptions.UserEntercode != null && _rpoOptions.OwnerEntercode != null) { writer.SetEncryption(PdfWriter.STRENGTH128BITS, _rpoOptions.UserEntercode, _rpoOptions.OwnerEntercode, PdfWriter.AllowPrinting); // 設定PDF權限 } writer.PageEvent = this; // 頁首頁尾設定 ReportPainter rp = new ReportPainter(doc, _rpoOptions, writer); doc.Open(); sMsg = i_fPainting.Invoke(rp, _rpoOptions); if (sMsg != null) { break; } doc.NewPage(); // 沒有資料時顯示文字 if (writer.PageNumber == 1) { rp.WriteText("無資料"); } doc.Close(); using var fs = new FileStream(_rpoOptions.OutputPath, FileMode.OpenOrCreate, FileAccess.Write); memoryStream.Seek(0, SeekOrigin.Begin); memoryStream.CopyTo(fs); } while (false); } catch { sMsg = $"{nameof(Paint)} unknwon exception. Call from {i_sMemberName} {i_sSourcePath}({i_nCodeLine})."; #if DEBUG System.Diagnostics.Debug.WriteLine(sMsg); #endif } return sMsg; } public override void OnCloseDocument(PdfWriter writer, Document document) { base.OnCloseDocument(writer, document); // 顯示每個頁碼的總頁數(僅此處可抓到) if (_rpoOptions.IsShowPageNumber) { _tFooterPageTotal.BeginText(); _tFooterPageTotal.SetFontAndSize(_rpoOptions.BaseFont, _rpoOptions.FontSize); _tFooterPageTotal.ShowTextAligned(PdfContentByte.ALIGN_LEFT, (writer.PageNumber - 1).ToString(), 0, 1, 0); _tFooterPageTotal.EndText(); } } } }