2017-04-21 47 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

呼叫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。微軟將此功能添加到Office文檔中,因爲它更正式地阻止用戶對文件進行未來更改,而不是簡單的文件許可權。對這些文件之一進行的任何更改都需要新的文件名。

推薦的OpenXml代碼將generate a Custom Property,所以當用戶下載文件時,它將被標記爲最終以阻止用戶編輯。

這裏是將添加自定義屬性的方法:

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; 
    } 

我寫了一個簡單的MVC應用程序生成標記爲最終你作爲一個參考實現一個空的Excel文件。 The code is hosted on GitHub。當你運行它時,點擊最右邊的菜單鏈接「下載Excel」。這將下載一個名爲Walter's Workbook的工作簿並且沒有數據。該excel將被標記爲final。 Custom Property的代碼是使用OpenXML Productivity Tool生成的。祝你的項目好運。

+0

重大疾病給了這一去。我的最終用戶可能會有更舊版本的Excel..office 2003。如果最終不使用OpenXML可能需要查看另一個庫..aspose是我之前使用過的,但它可能是昂貴的 –