声明
本篇文章为学习笔记,有错误或更好的方法请大佬们在评论区踢我下谢谢!
一、 插件准备工作
- 使用VS,在.NETFramework框架下创建一个控制台应用程序; 依次点击
- 工具->NuGet包管理器->管理解决方案的NuGet程序包; 选择浏览菜单,搜索 iTextSharp,找到后点击安装;
- 打开VS项目文件夹,在packages文件夹中
找到BouncyCastle.1.8.9和iTextSharp.5.5.13.3文件夹依次打开并提取lib文件夹中的dll文件。BouncyCastle.Crypto.dll和itextsharp.dll - 将dll文件放在Unity项目的Plugins文件夹下。
- 打开自己的unity编辑器目录“ \Editor\Data\MonoBleedingEdge\lib\mono\unityjit”,将"CodePages.dll"提取到unity项目的Plugins文件下(中文支持)。
二 、创建PDF表单
- 新建“FormTest.pdf”文件并打开,点击“表单”》“编辑表单”,设置好字段(WPS PDF不支持表单创建)。
在unity中创建“StreamingAssets/Document”文件目录,并将“FormTest.pdf”文件导入。
三、读取PDF模板并拷贝
//模板路径
string pdfTemplate =Application.streamingAssetsPath + "/Document/FormTest.pdf";
//导出文件路径
string outPdf = Application.persistentDataPath + "/Document/Form.pdf";
//检查导出导出目录是否存在 不存在则新建
if (!Directory.Exists(outPdf))
{
Directory.CreateDirectory(Application.persistentDataPath + " / Document");
}
//读取并拷贝模板
PdfReader pdfReader = new PdfReader(pdfTemplate);
FileStream fileStream = new FileStream(outPdf, FileMode.Create);
PdfStamper pdfStamper = new PdfStamper(pdfReader, fileStream);
四、 表单域赋值
4.1 添加中文支持
//注册CodePages
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
//创建字体
BaseFont font = BaseFont.CreateFont("C:\\WINDOWS\\FONTS\\STSONG.TTF",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
4.2 文本域赋值
pdfStamper.Writer.CloseStream = false;
//解除表单锁定
pdfStamper.FormFlattening = false;
AcroFields fields = pdfStamper.AcroFields;
//设置单个域属性(字段名,属性名,属性值)
fields.SetFieldProperty("name", "textfont", font, null);
fields.SetField("name", "小明");
fields.SetFieldProperty("six", "textfont", font, null);
fields.SetField("sex", "男");
fields.SetField("number", "330521");
//设置表单锁定,不设置此的话导出的pdf保留域,可修改,有域高亮但不会打印
pdfStamper.FormFlattening = true;
pdfStamper.Close();
4.3 图像域赋值
采用的思想是拷贝该图像域,修改好后直接替换。直接修改Image好像不起作用,没试成功!
pdfStamper.Writer.CloseStream = false;
//文本框锁定解除
pdfStamper.FormFlattening = false;
AcroFields fields = pdfStamper.AcroFields;string TestImage = Application.streamingAssetsPath +"/Textures/TVPS.png";
PushbuttonField imgField = fields.GetNewPushbuttonFromField("img");
imgField.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
imgField.ProportionalIcon = true;
imgField.Image = Image.GetInstance(TestImage);
fields.ReplacePushbuttonField("img", imgField.Field);
pdfStamper.FormFlattening = true;
pdfStamper.Close();
五、 打印文件
未验证协程是否有用,文件过大时会出现异常
IEnumerator PrintPDF(string path)
{
//等待文件准备好后开始打印(FillPDFFields())
WaitUntil wait = new WaitUntil(()=>FillPDFFields());
yield return wait;
Process process = new Process(); //系统进程
process.StartInfo.CreateNoWindow = true; //不显示调用程序窗口
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //隐藏打印信息
process.StartInfo.UseShellExecute = true; //采用操作系统自动识别模式
process.StartInfo.FileName = path; //要打印的文件路径
process.StartInfo.Verb = "print"; //指定执行的动作,打印:"print" 打开"open"
process.Start(); //开始打印
process.Close();
}
六、 画图
6.1 绘制曲线
SetColorStroke(strokeColor):画笔颜色
SetLineWidth():画笔粗细
MoveTo(x,y):画笔起点
LineTo(x,y):下一个点的坐标
Stroke():结束路径
//画图
PdfContentByte content = pdfStamper.GetOverContent(1); //获取上层内容(参数为页码)
BaseColor strokeColor = new BaseColor(0f, 1f, 0f,1f); //颜色如果为0-1f,f不要忘记
content.SetColorStroke(strokeColor); //设置笔画颜色
content.SetLineWidth(3);
content.MoveTo(0, 0); //起点
content.LineTo(50, 50);
content.LineTo(300, 100);
content.Stroke(); //结束笔画
6.2 绘制虚线
通过SetLineDash()函数设置虚线,里面的参数还没研究过,如果有大佬知道的麻烦评论区补充下谢谢!
content.SetLineDash(10, 1);
6.3 绘制多边形路径
使用ClosePathStroke()闭合路径并结束画笔,或分布
//content.ClosePathStroke();
content.ClosePath();
content.Stroke();
6.4 绘制多边形并填充颜色
SetColorFill(BaseColor):设置填充颜色
Fill():填充颜色并结束,无描边
FillStroke():填充颜色并结束,非闭合描边
ClosePathFillStroke():填充颜色并结束,闭合描边
content.SetColorFill(strokeColor); //设置填充颜色
content.Fill();
//FillStroke();
//ClosePathFillStroke();
七、文档占用检测
/// <summary>
/// 判断文档是否可以打开
/// </summary>
/// <param name="path">文档路径</param>
/// <returns>结果</returns>
private bool CanOpenDocument(String path)
{
try
{
FileStream fileStream = new FileStream(outPdf, FileMode.Open);
}
catch(IOException e)
{
Debug.Log("占用中");
return false;
}
return true;
}
可以配合协程使用,避免文件过大时,执行打印或其它操作导致的异常失败
WaitUntil wait = new WaitUntil(()=> CanOpenDocument(path));
IEnumerator PrintPDF(string path)
{
//填写或操作PDF文件
FillPDFFields();
WaitUntil wait = new WaitUntil(()=> CanOpenDocument(path));
yield return wait;
Debug.Log("成功打开后执行后续操作");
}