📈

SharePoint Online の Excel Services (SOAP API) を叩いてみる

に公開

はじめに

Excel Services を使用すると、SharePoint のドキュメント ライブラリに保存されている Excel ファイルを直接編集できます。一般的に、プログラムから Excel を編集する場合は Open XML SDK やサードパーティー製のコンポーネントを利用することが多いです。Excel Services を利用することで、それらを使用せずにセルの読み書き程度であれば簡単に実現できます。[1] SOAP で提供されているため、Visual Studio からは サービス参照の追加 を行うことで簡単に呼び出すことができます。

ただし、SharePoint Online の場合はこの方法に課題があります。SharePoint Online は OAuth に対応しているため、WCF ではアクセス許可が通りません。そのため、自分で HTTP ヘッダーを追加する必要があります。

サンプル コード

https://github.com/karamem0/samples/tree/main/sharepoint-excel-service-using-oauth

実行手順

アクセス トークンの取得方法については、以下の記事を参考にしてください。今回のサンプルではリフレッシュ トークンを利用したアクセス トークンの再取得も実装しています。

https://zenn.dev/karamem0/articles/2016_12_17_000000

WCF でカスタム HTTP ヘッダーを追加するには、Message Inspectors という機能を利用します。

IClientMessageInspector を実装するクラスを作成し、メッセージ送信前にアクセス トークンを追加します。

public class BearerClientMessageInspector : IClientMessageInspector
{

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        var property = new HttpRequestMessageProperty();
        property.Headers.Add("Authorization", "Bearer {{access-token}}");
        request.Properties[HttpRequestMessageProperty.Name] = property;
        return null;
    }

}

IEndpointBehavior を実装するクラスを作成し、ClientRuntime.ClientMessageInspectors にメッセージ インスペクターを追加します。

public class BearerEndpointBehavior : IEndpointBehavior
{

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.ClientMessageInspectors.Add(new BearerClientMessageInspector());
    }

}

SoapClient の EndpointBehaviors にビヘイビアーを追加します。

using (var client = new ExcelServiceSoapClient())
{
    client.Endpoint.EndpointBehaviors.Add(new BearerEndpointBehavior());
    var status = default(Status[]);
    var sessionId = client.OpenWorkbook(FilePath, "", "", out status);
    var cell = client.GetCellA1(sessionId, "Sheet1", "A1", false, out status);
    client.CloseWorkbook(sessionId);
}

おわりに

最終的には Graph Excel REST API の利用を推奨します。

脚注
  1. 現在では Excel COM を利用するケースはほとんどありません。 ↩︎

Discussion