You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

求助:如何在C#中读写Office 365 SharePoint在线Excel文件

嘿,刚好之前做过类似的需求,给你分享两种在C#里读写Office 365 SharePoint在线Excel文件的靠谱方法,都是基于你已经拥有该文件读写权限的前提哈~

方法一:使用Microsoft Graph API(微软官方推荐)

这是目前最现代的方式,微软官方主推,支持控制台、Web、桌面等各种应用场景,不用直接操作文件流就能读写单元格数据,非常方便。

准备工作

  • 先在Azure AD里注册一个应用:如果是桌面/控制台这类交互式应用,选「公共客户端」;如果是后台服务,选「机密客户端」。给应用分配Files.ReadWrite.All(针对所有文件)或者Sites.ReadWrite.All(针对站点)的权限——如果是用户上下文用委派权限,后台服务就用应用权限,记得让租户管理员授予管理员同意,不然会有权限报错。
  • 安装两个必备的NuGet包:
    Install-Package Microsoft.Graph
    Install-Package Microsoft.Identity.Client
    

代码示例

1. 认证获取Graph客户端

这里以后台服务的应用权限模式为例(不用用户登录):

using Microsoft.Graph;
using Microsoft.Identity.Client;

// 替换成你的Azure应用信息
var clientId = "你的Azure应用ID";
var tenantId = "你的Office 365租户ID";
var clientSecret = "你的应用密钥";

var confidentialClient = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithTenantId(tenantId)
    .WithClientSecret(clientSecret)
    .Build();

var authProvider = new ClientCredentialProvider(confidentialClient);
var graphClient = new GraphServiceClient(authProvider);

2. 读取Excel文件数据

直接读取指定工作表的指定范围,不用下载整个文件:

// 替换成你的文件信息:可以用文件ID,或者站点相对路径(比如"/sites/你的站点名/Shared Documents/测试.xlsx")
var fileId = "你的在线Excel文件ID";
var sheetName = "Sheet1"; // 替换成你的工作表名称

// 读取已使用的区域,也可以指定具体范围比如"A1:Z50"
var usedRange = await graphClient.Drives["你的Drive ID"].Items[fileId]
    .Workbook.Worksheets[sheetName]
    .UsedRange
    .Request()
    .GetAsync();

// 遍历打印数据
foreach (var row in usedRange.Values)
{
    Console.WriteLine(string.Join(", ", row));
}

小贴士:不知道文件ID的话,可以从SharePoint文件的URL里提取(URL里的id=参数就是),或者用Graph的搜索接口根据文件名查找。

3. 更新Excel文件数据

可以单独更新某个单元格,也可以批量更新范围:

// 示例:更新B2单元格的值
var updateRange = new WorkbookRange
{
    Values = new object[,] { { "这是更新后的值" } }
};

await graphClient.Drives["你的Drive ID"].Items[fileId]
    .Workbook.Worksheets[sheetName]
    .Range("B2")
    .Request()
    .PatchAsync(updateRange);

如果需要做复杂的Excel修改(比如插入行、设置格式),可以先把文件下载到本地修改,再上传覆盖原文件:

// 下载原文件到流
using var fileStream = new MemoryStream();
await graphClient.Drives["你的Drive ID"].Items[fileId]
    .Content
    .Request()
    .GetAsync()
    .Result.CopyToAsync(fileStream);

// 这里用Open XML SDK修改流里的Excel内容(需要安装DocumentFormat.OpenXml包)
// ... 你的修改逻辑 ...

// 上传覆盖原文件
fileStream.Position = 0;
await graphClient.Drives["你的Drive ID"].Items[fileId]
    .Content
    .Request()
    .PutAsync<DriveItem>(fileStream);
方法二:使用SharePoint Client Object Model(CSOM)

这是传统的SharePoint开发方式,适合已经熟悉CSOM的开发者,不需要依赖Azure AD应用,直接用SharePoint账号认证。

准备工作

  • 安装CSOM的NuGet包:
    Install-Package Microsoft.SharePointOnline.CSOM
    
  • 如果要解析Excel内容,还需要安装Open XML SDK:
    Install-Package DocumentFormat.OpenXml
    

代码示例

1. 认证获取ClientContext

using Microsoft.SharePoint.Client;
using System.Security;

var siteUrl = "你的SharePoint站点URL,比如https://你的租户.sharepoint.com/sites/你的站点名";
var userName = "你的Office 365账号";
var password = "你的密码(如果开了MFA,得用App密码)";

// 转换为安全字符串
var securePwd = new SecureString();
foreach (char c in password) securePwd.AppendChar(c);

var ctx = new ClientContext(siteUrl);
ctx.Credentials = new SharePointOnlineCredentials(userName, securePwd);

踩坑提醒:如果你的账号开启了MFA,直接用用户名密码会认证失败,得在Office 365里启用App密码,用App密码代替普通密码。

2. 读取Excel文件数据

CSOM本身不直接解析Excel,需要先把文件下载到流,再用Open XML读取:

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

// 获取文件对象
var fileRelativeUrl = "/sites/你的站点名/Shared Documents/测试.xlsx";
var file = ctx.Web.GetFileByServerRelativeUrl(fileRelativeUrl);
ctx.Load(file);
ctx.ExecuteQuery();

// 下载文件到内存流
using var memoryStream = new MemoryStream();
file.OpenBinaryStream().CopyTo(memoryStream);
memoryStream.Position = 0;

// 用Open XML读取数据
using var spreadsheetDoc = SpreadsheetDocument.Open(memoryStream, false);
var workbookPart = spreadsheetDoc.WorkbookPart;
var worksheetPart = workbookPart.WorksheetParts.First();
var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

foreach (var row in sheetData.Elements<Row>())
{
    foreach (var cell in row.Elements<Cell>())
    {
        // 处理共享字符串类型的单元格
        var cellValue = cell.InnerText;
        if (cell.DataType?.Value == CellValues.SharedString)
        {
            cellValue = workbookPart.SharedStringTablePart.SharedStringTable
                .Elements<SharedStringItem>()
                .ElementAt(int.Parse(cellValue)).InnerText;
        }
        Console.Write(cellValue + "\t");
    }
    Console.WriteLine();
}

3. 更新Excel文件数据

先修改流里的Excel内容,再上传覆盖原文件:

// 重新读取文件到可写流
memoryStream.Position = 0;
using var editableDoc = SpreadsheetDocument.Open(memoryStream, true);
var workbookPart = editableDoc.WorkbookPart;
var worksheetPart = workbookPart.WorksheetParts.First();
var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

// 示例:修改第一行第一列的单元格值
var firstRow = sheetData.Elements<Row>().First();
var firstCell = firstRow.Elements<Cell>().First();
firstCell.CellValue = new CellValue("更新后的内容");
firstCell.DataType = new EnumValue<CellValues>(CellValues.String);

// 保存修改
worksheetPart.Worksheet.Save();
memoryStream.Position = 0;

// 上传覆盖原文件
file.SaveBinaryStream(memoryStream);
ctx.ExecuteQuery();

两种方法各有优劣:Graph API更灵活,支持更多场景,不用处理复杂的Excel解析;CSOM更贴近传统SharePoint生态,适合已有CSOM技术栈的项目。根据你的实际需求选就行~

内容的提问来源于stack exchange,提问作者archana

火山引擎 最新活动