You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
4.8 KiB
135 lines
4.8 KiB
|
|
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<ReportPainter, ReportCanvasOptions, string> 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();
|
|
}
|
|
}
|
|
}
|
|
}
|