基于C#的SharePoint自动化:文档读取与数据库导入技术问询
1. C# 连接 SharePoint 的两种核心方式
针对 SharePoint Online(云版)
官方推荐用Microsoft Graph SDK,步骤如下:
- 在Azure AD注册应用,授予
Files.Read.All、Sites.Read.All等必要的应用权限(因为是Windows服务后台运行,不要用委派权限) - 安装NuGet包:
Microsoft.Graph、Microsoft.Graph.Auth - 代码示例:
using Microsoft.Graph; using Microsoft.Graph.Auth; using Microsoft.Identity.Client; var clientId = "你的Azure应用Client ID"; var clientSecret = "你的Azure应用Client Secret"; var tenantId = "你的租户ID"; var confidentialClientApplication = ConfidentialClientApplicationBuilder .Create(clientId) .WithTenantId(tenantId) .WithClientSecret(clientSecret) .Build(); var authProvider = new ClientCredentialProvider(confidentialClientApplication); var graphClient = new GraphServiceClient(authProvider); // 测试连接:获取指定站点文档库根文件夹 var driveRoot = await graphClient.Sites["你的站点ID"].Drive.Root.Request().GetAsync();
针对本地/企业内部部署的 SharePoint Server
用SharePoint CSOM(客户端对象模型),步骤:
- 安装NuGet包:
Microsoft.SharePointOnline.CSOM(兼容2016及以上版本的本地SharePoint) - 代码示例(用户名密码/NTLM认证):
using Microsoft.SharePoint.Client; using System.Security; var siteUrl = "http://你的SharePoint站点URL"; var userName = "域账号/用户名"; var password = "密码"; using (var context = new ClientContext(siteUrl)) { // 密码转安全字符串 var securePassword = new SecureString(); foreach (char c in password) securePassword.AppendChar(c); // 云版用SharePointOnlineCredentials,本地用NetworkCredential context.Credentials = new SharePointOnlineCredentials(userName, securePassword); // context.Credentials = new NetworkCredential(userName, password, "你的域"); // 测试连接:获取站点信息 var web = context.Web; context.Load(web); await context.ExecuteQueryAsync(); }
2. 读取文件夹并检测新文档
核心是记录已处理文档的唯一标识(比如文档ID、最后修改时间),每次轮询时对比筛选未处理的新文档。已处理记录可以存在本地JSON文件、数据库或者服务内存缓存中。
检测新文档的示例代码(CSOM版)
// 本地存储已处理文档ID的集合 var processedDocumentIds = new HashSet<string>(); // 从本地文件/数据库加载已处理记录 LoadProcessedIds(processedDocumentIds); using (var context = new ClientContext(siteUrl)) { // 配置认证... var docLibrary = context.Web.Lists.GetByTitle("你的文档库名称"); var rootFolder = docLibrary.RootFolder; context.Load(rootFolder.Files); await context.ExecuteQueryAsync(); // 筛选未处理的Excel文档 var newDocs = rootFolder.Files .Where(f => f.Name.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase) && !processedDocumentIds.Contains(f.UniqueId.ToString())) .ToList(); foreach (var doc in newDocs) { // 下载文档到本地临时目录 var fileStream = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, doc.ServerRelativeUrl); using (var localStream = File.Create($"C:\\Temp\\{doc.Name}")) { fileStream.Stream.CopyTo(localStream); } // 读取Excel数据并入库(示例用EPPlus) ImportExcelToDatabase($"C:\\Temp\\{doc.Name}"); // 标记为已处理 processedDocumentIds.Add(doc.UniqueId.ToString()); } // 保存更新后的已处理记录 SaveProcessedIds(processedDocumentIds); } // Excel数据入库示例(需安装NuGet包EPPlus) void ImportExcelToDatabase(string filePath) { using (var package = new ExcelPackage(new FileInfo(filePath))) { var worksheet = package.Workbook.Worksheets.First(); // 跳过表头,从第二行开始读取 for (int row = 2; row <= worksheet.Dimension.End.Row; row++) { var col1Value = worksheet.Cells[row, 1].Text; var col2Value = worksheet.Cells[row, 2].Text; // 这里替换成你的数据库插入逻辑(EF/ADO.NET都可以) // DbContext.YourTable.Add(new YourModel { Col1 = col1Value, Col2 = col2Value }); } // DbContext.SaveChanges(); } }
Windows服务轮询逻辑
用Timer组件定期触发同步任务,比如每小时执行一次:
private Timer _syncTimer; protected override void OnStart(string[] args) { // 初始化定时器:立即执行一次,之后每3600秒(1小时)执行一次 _syncTimer = new Timer(SyncDocuments, null, 0, 3600000); } private async void SyncDocuments(object state) { // 执行上面的文档同步与数据入库逻辑 } protected override void OnStop() { _syncTimer?.Dispose(); }
推荐的开源资源
- SharePointPnP/SharePointPnP-Sites-Core:微软PnP团队维护的CSOM扩展库,封装了大量SharePoint操作的实用方法,能大幅简化文档库、列表的读写逻辑
- microsoftgraph/msgraph-sdk-dotnet-samples:Microsoft Graph SDK的官方示例仓库,包含完整的文档库操作、文件下载等场景代码
内容的提问来源于stack exchange,提问作者Favini
相关产品推荐
相关产品推荐

