2017-04-21 26 views
2

Open XMLを使用してMVCからExcelドキュメントを生成しています。OpenXMLを使用してMVCコントローラからワークブックを読み取る

コードは以下の通りです:

public ActionResult ExcelReport() 
{ 
    var custId = 1234; //ToDo get from session when it is set 

    using (MemoryStream mem = new MemoryStream()) 
    { 
    ExcelReportGenerator excel = new ExcelReportGenerator(); 

    excel.CreateExcelDoc(mem); 

    var reportName = string.Format("MyReport_{0}.xlsx", custId); 

    return File(mem.ToArray(), System.Net.Mime.MediaTypeNames.Application.Octet, reportName); 
    } 

} 

マイCreateExcelDoc方法は以下の通りです:

public void CreateExcelDoc(MemoryStream mem) 
{ 
    SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(mem, SpreadsheetDocumentType.Workbook); 

    //SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(mem, false); 

    //Code removed for brevity 

    worksheetPart.Worksheet.Save(); 
    spreadsheetDocument.Close(); 

} 

期待通りにExcelシートをダウンロードして作成する方法で。しかし、ワークブックを読み取り専用にして、Memストリームを渡してisEditableをfalseに設定しようとしましたが、エラーが発生したときにYSODを取得しました。Exception Details: System.IO.FileFormatException: Archive file cannot be size 0.

答えて

1

あなたのExcelを読みやすくするための簡単な方法はProtect the worksheet (see Step 2 at link)です。私はこのテクニックを使用していますnew version of the reference implementation MVCをプッシュしている

workSheet.Append(new SheetProtection() { Sheet = true, Objects = true, Scenarios = true }); 

これを行うには、OpenXMLのコードは、シートごとに1行です。 Excel 2007では、SheetProtectionがサポートされているようです。ここでは、FinalというマークはExcel 2013以降でのみサポートされています。

+0

これはまさに私が必要とするものです - ありがとう:) –

1

コールSpreadsheetDocument.Open読み取り専用ファイルにはなりません。 It merely opens the memory stream in read only mode. (isEditable is false)これは、ストリームがコードの残りの部分によって変更されるのをロックします。これは、その呼び出しを追加する前にExcelが正常に生成された理由と、その呼び出しを追加した後に空のアーカイブ例外が発生する理由を説明しています。そのためにはSpreadsheetDocument.Openを使用しないでください。

Excelを読み取り専用ファイルとして送信することはお勧めできません。ユーザーは任意のオペレーティングシステム上でそれをダウンロードして名前を変更し、必要に応じてファイルのアクセス権を変更することができます。

私がお勧めするのはopenXMLコードmark your Excel as finalを追加することです。 Microsoftはこの機能をOfficeドキュメントに追加しました。これは、単純なファイルアクセス許可ではなく、ユーザーが将来的にファイルを変更することを正式には避けているからです。これらのファイルのいずれかを変更するには、新しいファイル名が必要です。

推奨されるOpenXmlコードはgenerate a Custom Propertyですので、ユーザーがファイルをダウンロードすると、ユーザーの編集を妨げるようにFinalとマークされます。私はリファレンス実装としてあなたのための最終的なとしてマークされ、空のExcelファイルを生成する単純なMVCアプリケーションを書いた

private void GenerateCustomFilePropertiesPart1Content(CustomFilePropertiesPart customFilePropertiesPart1) 
    { 
     Op.Properties properties2 = new Op.Properties(); 
     properties2.AddNamespaceDeclaration("vt", "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"); 

     Op.CustomDocumentProperty customDocumentProperty1 = new Op.CustomDocumentProperty() { FormatId = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", PropertyId = 2, Name = "_MarkAsFinal" }; 
     Vt.VTBool vTBool1 = new Vt.VTBool(); 
     vTBool1.Text = "true"; 

     customDocumentProperty1.Append(vTBool1); 

     properties2.Append(customDocumentProperty1); 

     customFilePropertiesPart1.Properties = properties2; 
    } 

:ここ

は、カスタムプロパティを追加する方法です。 The code is hosted on GitHub。それを実行するときは、右端のメニューリンク "Download Excel"をクリックします。これにより、Walter's Workbookという名前のワークブックとデータなしのExcelがダウンロードされます。エクセルは最終的なものとしてマークされます。カスタムプロパティのコードは、OpenXML Productivity Toolで生成されました。あなたのプロジェクトに幸運。

+0

私のエンドユーザーはExcel 2003の古いバージョンを持つ可能性があります。 OpenXMLの最終作業が別のライブラリを調べなければならないかもしれません。目的は私が前に使用したものですが、それは高価になる可能性があります –

関連する問題