SharePointのExcelへの標準エクスポートオプションは、かなり珍しい方法で機能します。 エクスポートボタンをクリックすると、SharePointはExcelが開く特別な形式の要求ファイルを提供し、Excel自体がデータをドラッグします。
このアプローチの利点は、接続があるためExcelのデータを更新できることです。 しかし、さらに不利な点があります:
- データを取得するには、コンピューターにExcelをインストールする必要があります。
- 結果のドキュメントでは、列名にInternalNameフィールドが使用されます。
- 受信したドキュメントは「生の」データ形式を使用しますが、これは常に適切とは言えません。
少量のコードで、ユーザーが何にも気付かないように、標準のエクスポート機能を独自のものに置き換えることができます。
エクスポートボタンの置換
リボンの既存の要素を置き換えるには、既存の要素のIDと等しい
Location
パラメーターを使用して、新しい
CommandUIDefinition
を追加する必要があります。 すべての標準要素は、ファイル
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\ 14 \TEMPLATE\GLOBAL\XML\CMDUI.XML
にあります
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\ 14 \TEMPLATE\GLOBAL\XML\CMDUI.XML
for SharePoint 2010(または
15 for SharePoint 2013)。
Excelのエクスポートボタンを置き換えるには、Idが
Ribbon.List.Actions.ExportToSpreadsheet
および
Ribbon.Library.Actions.ExportToSpreadsheet
と等しいボタンを見つけて、プロジェクトに完全にコピーする必要があります。 新しい要素の
Location
として、これらのIDを指定する必要があります。
コピーペーストがたくさん <CommandUIDefinitions> <CommandUIDefinition Location="Ribbon.Library.Actions.ExportToSpreadsheet"> <Button Id="Ribbon.Library.Actions.ExportToSpreadsheet-Replacement" Sequence="40" Command="ExportToSpreadsheet-Replacement" Image16by16="/_layouts/$Resources:core,Language;/images/formatmap16x16.png" Image16by16Top="-152" Image16by16Left="-32" Image32by32="/_layouts/$Resources:core,Language;/images/formatmap32x32.png" Image32by32Top="-352" Image32by32Left="0" LabelText="$Resources:core,cui_ButExportToSpreadsheet;" ToolTipTitle="$Resources:core,cui_ButExportToSpreadsheet;" ToolTipDescription="$Resources:core,cui_STT_ButExportListToSpreadsheet;" TemplateAlias="o2" /> </CommandUIDefinition> <CommandUIDefinition Location="Ribbon.List.Actions.ExportToSpreadsheet"> <Button Id="Ribbon.List.Actions.ExportToSpreadsheet-Replacement" Sequence="40" Command="ExportToSpreadsheet-Replacement" Image16by16="/_layouts/$Resources:core,Language;/images/formatmap16x16.png" Image16by16Top="-152" Image16by16Left="-32" Image32by32="/_layouts/$Resources:core,Language;/images/formatmap32x32.png" Image32by32Top="-352" Image32by32Left="0" LabelText="$Resources:core,cui_ButExportToSpreadsheet;" ToolTipTitle="$Resources:core,cui_ButExportToSpreadsheet;" ToolTipDescription="$Resources:core,cui_STT_ButExportListToSpreadsheet;" TemplateAlias="o1" /> </CommandUIDefinition> </CommandUIDefinitions>
Id="Ribbon.Calendar.Calendar.Actions.ExportToSpreadsheet"
カレンダー用の別のボタンもあり、同じことを行うことができます。
コントロールを作成する
ボタンはサーバーコードを呼び出す必要があります。 動作を標準ボタンに
似せるには 、各ページに配置される
DelegateControlを作成するのが最善です。
Id="AdditionalPageHead"
コンテナがあります:
<Control Id="AdditionalPageHead" Sequence="1000" ControlAssembly="$SharePoint.Project.AssemblyFullName$" ControlClass="$SharePoint.Type.7fd7c6f0-4eda-48ce-ac8f-aa9f9d2666ac.FullName$"/>
カスタムボタンは、コントロールによって処理される
PostBackを呼び出します。 リストビューページでボタンをクリックすると、追加のパラメータを渡す必要はありません。 また、リストビューをWebパーツとして通常のページに追加した後、リストIDとビューをサーバーに転送する必要があります。
残念ながら、ボタンがクリックされたビューのIDを取得するのは簡単なことではありません。 したがって、リストIDを渡すことのみに制限します。
<CommandUIHandlers> <CommandUIHandler Command="ExportToSpreadsheet-Replacement" CommandAction="javascript:(function(){var x=SP.ListOperation.Selection.getSelectedList(); if (x) {__doPostBack('ExportToSpreadsheet-Replacement', x);}})();" /> </CommandUIHandlers>
次に、サーバーで、リストビューページまたは通常のページでボタンが押されているかどうかを確認する必要があります。
protected override void OnLoad(EventArgs e) { if (this.Page.Request["__EVENTTARGET"] == "ExportToSpreadsheet-Replacement") { var spContext = SPContext.Current; SPList list; SPView view; if (spContext.ViewContext.View != null) { list = spContext.List; view = spContext.ViewContext.View; } else { var listId = new Guid(this.Page.Request["__EVENTARGUMENT"]); var web = spContext.Web; list = web.Lists[listId]; view = list.DefaultView; } ExportData(list.Title + " - " + view.Title, GetDataTable(list, view)); } }
ビューデータテーブルの取得は非常に簡単です。
private static System.Data.DataTable GetDataTable(SPList list, SPView view) { var query = new SPQuery(view); SPListItemCollectionPosition position; var flags = SPListGetDataTableOptions.UseBooleanDataType | SPListGetDataTableOptions.UseCalculatedDataType; var result = list.GetDataTable(query, flags, out position); while (position != null) { list.AppendDataTable(query, flags, result, out position); } return result; }
Excelファイルの生成
最後の手順は、Excelファイルを作成してクライアントに提供することです。 Excelを生成する最も簡単な方法の1つは、ClosedXmlライブラリ(
http://closedxml.codeplex.com/ )を使用することです。
private void ExportData(string title, System.Data.DataTable table) { var wb = new XLWorkbook(); var ws = wb.Worksheets.Add(title); ws.Cell(1, 1).InsertTable(table); var response = this.Page.Response; response.Clear(); response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; var filename = title+".xlsx"; response.AddHeader("content-disposition", GetContentDisposition(filename));
メソッドの最初の3行は実際にExcelドキュメントを形成し(ClosedXmlのおかげです)、他のすべてはクライアントにファイルを送信するためのコードです。
content-disposition
応答ヘッダーは、ブラウザごとに非常に異なって認識されるため、正しいロシア名のファイルを指定するには、タンバリンで踊る必要があります。
StackOverflowで正しい
content-disposition
ヘッダーを生成するコードを見つけました
stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http private string GetContentDisposition(string filename) { var request = this.Page.Request; string contentDisposition; if (request.Browser.Browser == "IE" && (request.Browser.Version == "7.0" || request.Browser.Version == "8.0")) contentDisposition = "attachment; filename=" + Uri.EscapeDataString(filename); else if (request.UserAgent != null && request.UserAgent.ToLowerInvariant().Contains("android"))
おわりに
すべてが実稼働環境で機能するには、ClosedXml.dllファイルとDocumentFormat.OpenXml.dllファイルをパッケージに追加する必要があります。 リボンとコントロールボタンは、サイトレベルまたはWebレベルの1つの機能に配置する必要があります。
プロジェクト全体はリンクで見ることができます
-spsamples.codeplex.com/SourceControl/latest#ExportToExcel準備ができたWSPファイルはこちら
-spsamples.codeplex.com/releases/view/117220ほとんどのコードはユニバーサルであり、SharePointに依存しません。 ASP.NETプロジェクトでも同様のアプローチを使用できます。