第一步要先裝 Openxml SDK 2.0, 然後引用DocumentFormat.Openxml.dll。
引用名稱空間
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Linq;
Openxml 只能產生Office2007的文檔,並且需要Linq。
關於Excel.xlsx:
office 2007的excel 實質是zip檔案, 把副檔名改為.zip後,我們可以看到裡面是一些xml 檔案
excel的主要內容都在xl目錄下,excel資料儲存在sharedString.xml檔案中,worksheets目錄存放的是worksheet對應的檔案。
有點時候我們產生的檔案不能正常開啟, 我們可以通過這個方式去對比和能開啟的檔案有啥區別,找到出錯原因。
Openxml Excel 結構:
1.建立SpreadsheetDocument, 這個相當於excel檔案級, SpreadsheetDocument.Create;
2. 建立WorkbookPart,在代碼中主要使用這個相當於xml的root elements, spreadSheet.AddWorkbookPart(), 雖然是"Add"方法, 但你只能加一個。
3. 初始workbookpart
Code
spreadSheet = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook);
WorkbookPart workbookPart = spreadSheet.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
4. 建立WorksheetPart, 這個就是excel sheets的管理類了, 這個可以參加sdk的how to 裡的方法
5. 建立SharedStringTablePart, 這個管理excel的內容, 不管你的資料是在那個excel worksheet裡, cell裡的值都是存在sharestringtable裡的, 然後通過relationshipID進行關聯。這裡有有一點需要注意, sdk裡沒有提及。如果要建立多個worksheet, 那麼一定要設定SharedStringTable 的Count 和UniqueCount 值。 否則建立多個worksheet, 產生的excel 在開啟時會報錯。
shareStringPart.SharedStringTable = new SharedStringTable();
shareStringPart.SharedStringTable.Count = 1;
shareStringPart.SharedStringTable.UniqueCount = 1;
6. 寫入cell值:
先把值寫入sharestringtable,參加sdk裡InsertSharedStringItem方法, 傳回值對應的id。
然後利用sdk 提供的樣本方法InsertCellInWorksheet, 建立一個新cell
最後把值和cell 做關聯
Code
int index = InsertSharedStringItem(text, shareStringPart);
Cell cell = InsertCellInWorksheet(name, Convert.ToUInt32(i + startx), worksheetPart);
cell.CellValue = new CellValue(index.ToString());
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
worksheetPart.Worksheet.Save();
每寫一個cell 都要執行以下worksheetPart.Worksheet.Save();
7. 建立多個excel worksheet:
通過workbookPart.Workbook 獲得 Sheets 集合元素
建立worksheetpart
建立Worksheet
通過workbookPart.GetIdOfPart獲得新worksheetpart的relationID
通過relationID 建立新的sheet。
append 建立的sheet到sheets 合集裡
執行worksheetPart.Worksheet.Save();
Asp.net 匯出 Openxml excel
1. 添加System.IO名稱空間引用
2. MemoryStream ms = new MemoryStream(); 用MemoryStream 代替常規的檔案流
3. 建立 openxml的 excel 檔案
4. 下載:
Code
Response.Clear();
Response.ClearHeaders();
Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");
Response.ContentType = "application/vnd.ms-excel.sheet.binary.macroEnabled.12";
Response.AddHeader("Content-Disposition", "attachment; filename=DataView.xlsx");
ms.Position = 0;
byte[] buffer = new byte[4096];
int i = 0;
long length = 0;
while (length < ms.Length)
{
i = ms.Read(buffer, 0, 4096);
Response.OutputStream.Write(buffer, 0, i);
length += i;
};
ms.Dispose();
Response.Flush();
Response.End();
這裡有一點要注意, 我原先用下面的方法:
byte[] buffer = ms.GetBuffer();
Response.OutputStream.Write(buffer, 0, buffer.Length);
這樣是有問題的, 因為memorystring有兩個長度, 一個是位元組長度,另一個是佔用空間長度, 因此用GetBuffer產生byte[] 是memory佔用的空間的長度, 而不是內容的實際長度, 這樣導致response出的檔案, 不能正常開啟。
我封裝了一下Openxml,供大家下載共同學習/Files/skyfei/OpenXMLExcel.rar