需要装的包:FreeSpire.PDF、Microsoft.SharePointOnline.CSOM、Microsoft.SharePoint.Client、AlibabaCloud.SDK.Dysmsapi20170525还有一些基础包,会有提示的,这里就不列出来了。
我的这个是根据PDF上的表格的唯一键,来确定到需要盖章的坐标,有些参数需要自己修改一下。
正文代码
using Spire.Pdf;
using Spire.Pdf.Annotations;
using System.Drawing;
using Spire.Pdf.Annotations.Appearance;
using Spire.Pdf.Graphics;
using Spire.Pdf.General.Find;
using OfficeExtend.Helper.SharePoint;
using System;
using System.IO;
using Microsoft.SharePoint;
using System.Web;
using System.Net;
using OfficeExtend;
using Microsoft.SharePoint.Client;
namespace ConsoleApp1
{
public class Program
{
public static void Main(string[] args)
{
string officeUrl = "sharepoint的文件地址";
string username = "****";//账号
string password = "****";//密码
//站点地址
string weburl = "sharepoint的站点地址";
//访问令牌
var fwlp = SharePointClientContextHelper.GetClientContext(weburl, username, password);
string sealfilename = GaizhangPDF("A/0", "favicon (1)", officeUrl, fwlp);//盖章
//上传文件到sharepoint
string _UploadedFilePath = sealfilename;
string _SharePointPath = "文档库的listid";//id()需要转urlcode,这个很重要,不然会转guid失败
SaveBinaryDirect(fwlp, _SharePointPath, _UploadedFilePath );
Console.ReadLine();
}
/// <summary>
/// 根据列表文字坐标给PDF文件+印章,返回保存文件的地址
/// </summary>
/// <param name="gjj">列表关键字</param>
/// <returns></returns>
public static string GaizhangPDF(string gjj, string name, string officeUrl, ClientContext client)
{
try
{
string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(officeUrl);// 没有扩展名的文件名
string filename = FileCommon._basePath + "/" + fileNameWithoutExtension + ".pdf";
//从o365文档库下载到本地
FileHelper.DownloadFileViaRestAPI(officeUrl, client.Credentials, filename);
//首先新建一个PDF文档对象并加载要添加印章的文档。
PdfDocument doc = new PdfDocument();
doc.LoadFromFile(filename);
#region xy坐标获取
int x = 0;//x坐标
int y = 0;//y坐标
PdfTextFind[] result = null;
foreach (PdfPageBase pagefor in doc.Pages)
{
TextFindParameter parameter = new TextFindParameter();
result = pagefor.FindText(gjj, parameter).Finds;
int i = 0;
foreach (PdfTextFind text in result)
{
//获取横向的坐标,宽度和高度
PointF pf = text.Position;
SizeF size = text.Size;
//关键字只有一个的情况正常走
if (result.Length == 1)
{
y = Convert.ToInt32(pf.Y);
}
if (result.Length < 1)
{
return "查询不到该版本号坐标";
}
else
{
if (i >= 1 && size.Width < 30)
{
y = Convert.ToInt32(pf.Y);
}
}
i++;
}
}
foreach (PdfPageBase pagefor in doc.Pages)
{
TextFindParameter parameter = new TextFindParameter();
result = pagefor.FindText("批准", parameter).Finds;
int i = 0;
foreach (PdfTextFind text in result)
{
//获取横向的坐标,宽度和高度
PointF pf = text.Position;
SizeF size = text.Size;
if (result.Length == 1)
{
x = Convert.ToInt32(pf.X);
}
if (result.Length < 1)
{
return "查询不到坐标";
}
else
{
if (i >= 1 && size.Width < 30)
{
x = Convert.ToInt32(pf.X);
}
}
i++;
}
}
#endregion
//获取文档的第一页。
PdfPageBase page = doc.Pages[0];
//新建一个PdfRubberStampAnnotation对象,指定其注释的范围和大小。
PdfRubberStampAnnotation loStamp = new PdfRubberStampAnnotation(new RectangleF(new PointF(x - 7, y - 15), new SizeF(120, 120)));
//实例化一个PdfAppearance对象。
PdfAppearance loApprearance = new PdfAppearance(loStamp);
//加载用作印章的图片。
PdfImage image = PdfImage.FromFile(@"C:\Users\lenovo\Downloads\" + name + ".ico");
//新建一个PDF模板,并在模板里绘制图片。
PdfTemplate template = new PdfTemplate(160, 160);
template.Graphics.DrawImage(image, 0, 0);
loApprearance.Normal = template;
loStamp.Appearance = loApprearance;
//在PDF文档添加印章。
page.AnnotationsWidget.Add(loStamp);
string time = DateTime.Now.ToString("F");
//保存文档。
string output = filename;
doc.SaveToFile(output);
return output;
}
catch (Exception e)
{
return $"失败信息:{e}";
throw;
}
}
//上传文件到sharepoint
public static void SaveBinaryDirect(ClientContext ctx, string libraryName, string filePath)
{
Web web = ctx.Web;
// Ensure that target library exists, create if is missing
//Guid.Parse(libraryName)转成guid
List docs = ctx.Web.Lists.GetById(Guid.Parse(libraryName));
ctx.Load(docs, l => l.RootFolder);
// Get the information about the folder that will hold the file
ctx.Load(docs.RootFolder, f => f.ServerRelativeUrl);
ctx.ExecuteQuery();
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
Microsoft.SharePoint.Client.File.SaveBinaryDirect(ctx, string.Format("{0}/{1}", docs.RootFolder.ServerRelativeUrl, System.IO.Path.GetFileName(filePath)), fs, true);
}
}
}
}
访问令牌方法
using Microsoft.SharePoint.Client;
using System;
using System.Security;
///这个是上面需要到的方法访问令牌方法
namespace OfficeExtend.Helper.SharePoint
{
public class SharePointClientContextHelper
{
public static ClientContext GetClientContext(string weburi,string loginname, string loginpwd)
{
try
{
var sercured_password = new SecureString();
foreach (var c in loginpwd)
{
sercured_password.AppendChar(c);
}
SharePointOnlineCredentials onlineCredentials = new SharePointOnlineCredentials(loginname, sercured_password);
ClientContext ctx = new ClientContext(weburi);
ctx.Credentials = onlineCredentials;
// The SharePoint web at the URL.
//Web web = ctx.Web;
//ctx.Load(web);
//ctx.ExecuteQuery();
return ctx;
}
catch (Exception)
{
return null;
}
}
}
}
获取当前运行程序代码(可有可无)
using PdfRead = iTextSharp.text.pdf;
using Microsoft.Office.Core;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Word = Microsoft.Office.Interop.Word;
using System.Diagnostics;
using Hangfire;
using DocumentFormat.OpenXml.Drawing.Charts;
using OfficeExtend.Helper;
using OfficeExtend.Models;
//直接创这个类就行了,也是上面需要用到的方法
public class FileCommon
{
public static string _basePath
{
get
{
var path = "";
if (System.Web.HttpContext.Current != null)
{
//path = System.Web.HttpContext.Current.Server.MapPath("").TrimEnd('/');
path = AppDomain.CurrentDomain.BaseDirectory;
}
else //非web程序引用
{
path = AppDomain.CurrentDomain.BaseDirectory;
}
path = path.Replace("\\", "/").TrimEnd('/');
return path;
}
}
}