using System.Dynamic;
using DynamicExpresso;
using iTextSharp.text;
using iTextSharp.text.pdf;
using Newtonsoft.Json.Linq;
namespace PdfSign;
public class SignService
{
public static string PdfSign(List<SignOpt> signOpts, string pdfName)
{
var beforeFileName = pdfName; //签名之前文件名
var afterFileName = pdfName + "_sign"; //签名之后文件名
var idx = 0;
foreach (var opt in signOpts)
{
//创建盖章后生成pdf
var outputPdfStream =
new FileStream(afterFileName + ".pdf", FileMode.Create, FileAccess.Write, FileShare.None);
//读取原有pdf
var pdfReader = new PdfReader(beforeFileName + ".pdf");
var pdfStamper = new PdfStamper(pdfReader, outputPdfStream);
//读取页数
var pdfPageSize = pdfReader.NumberOfPages;
//读取pdf文件第一页尺寸,得到 With 和 Height
var size = pdfReader.GetPageSize(1);
//通过表达式计算出签署的绝对坐标
var locationX = Eval<float>(opt.LocationX, new { size.Width, size.Height });
var locationY = Eval<float>(opt.LocationY, new { size.Width, size.Height });
if (opt.LastPage)
{
//盖章在最后一页
var pdfContentByte = pdfStamper.GetOverContent(pdfPageSize);
var gs = new PdfGState
{
FillOpacity = opt.Opacity
};
pdfContentByte.SetGState(gs);
switch (opt.SignType.ToLower())
{
case "image":
//获取图片
var image = Image.GetInstance(opt.FileName);
//设置图片比例
image.ScalePercent(opt.ScalePercent);
//设置图片的绝对位置,位置偏移方向为:左到右,下到上
image.SetAbsolutePosition(locationX, locationY);
//图片添加到文档
pdfContentByte.AddImage(image);
break;
case "text":
if (string.IsNullOrWhiteSpace(opt.Text))
continue;
var font = BaseFont.CreateFont();
var text = Eval<string>(opt.Text, new { Date = DateTime.Now.ToString("yyyy-MM-dd") });
//开始写入文本
pdfContentByte.BeginText();
pdfContentByte.SetColorFill(
new BaseColor(opt.FontColor.R, opt.FontColor.G, opt.FontColor.B));
pdfContentByte.SetFontAndSize(font, opt.FontSize);
pdfContentByte.SetTextMatrix(0, 0);
pdfContentByte.ShowTextAligned(Element.ALIGN_CENTER, text,
locationX, locationY, opt.Rotation);
pdfContentByte.EndText();
break;
}
}
pdfStamper.Close();
pdfReader.Close();
idx++;
if (idx >= signOpts.Count) continue;
//文件名重新赋值
beforeFileName = afterFileName;
afterFileName += "_sign";
}
return afterFileName + ".pdf";
}
//计算动态表达式的值
public static T? Eval<T>(string expr, object context)
{
if (string.IsNullOrWhiteSpace(expr))
return default;
var target = new Interpreter();
var input = JObject.FromObject(context);
target.SetVariable("input", input.ToObject<ExpandoObject>());
return target.Eval<T>(expr);
}
}