[英]Export to Excel using Open XML. But Last cell not filling up
我使用此代碼片段使用 Open XML 將數據導出到 Excel。
代碼在 VB.Net 中,所以我將其轉換為 C#。 它工作正常,只有一個(煩人的)故障。 最后一個單元格 (Z5) 是空白的。 當我使用 VB.Net 版本時,它會填充所有單元格。 我手動比較了 C# 與 VB.Net 代碼,但它的功能逐字節相似。 但它仍然無法填滿最后一個單元格。 知道為什么嗎?
代碼的 C# 版本如下供您參考:
protected void Export()
{
Response.ClearHeaders();
Response.ClearContent();
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
//"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" '"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" '"application/vnd.ms-excel"
Response.AddHeader("content-disposition", "attachment; filename=Test.xlsx");
Response.Charset = "";
this.EnableViewState = false;
MemoryStream ms = new MemoryStream();
SpreadsheetDocument objSpreadsheet = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook);
WorkbookPart objWorkbookPart = objSpreadsheet.AddWorkbookPart();
objWorkbookPart.Workbook = new Workbook();
WorksheetPart objSheetPart = objWorkbookPart.AddNewPart<WorksheetPart>();
objSheetPart.Worksheet = new Worksheet(new SheetData());
Sheets objSheets = objSpreadsheet.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
Sheet objSheet = new Sheet();
objSheet.Id = objSpreadsheet.WorkbookPart.GetIdOfPart(objSheetPart);
objSheet.SheetId = 1;
objSheet.Name = "mySheet";
objSheets.Append(objSheet);
for (int intRow = (int)('A'); intRow <= (int)('Z'); intRow++)
{
for (uint intCol = 1; intCol <= 5; intCol++)
{
Cell objCell = InsertCellInWorksheet(Convert.ToString((char)intRow), intCol, objSheetPart);
objCell.CellValue = new CellValue("This was a test: " + Convert.ToString((char)intRow) + intCol.ToString());
objCell.DataType = new EnumValue<CellValues>(CellValues.String);
objSpreadsheet.WorkbookPart.Workbook.Save();
}
}
objSpreadsheet.WorkbookPart.Workbook.Save();
objSpreadsheet.Close();
ms.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
private static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart)
{
Worksheet worksheet = worksheetPart.Worksheet;
var sheetData = worksheet.GetFirstChild<SheetData>();
string cellReference = columnName + rowIndex;
// If the worksheet does not contain a row with the specified row index, insert one.
Row row;
if (sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex).Count() != 0)
{
row = sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex).First();
}
else
{
row = new Row { RowIndex = rowIndex };
sheetData.Append(row);
}
// If there is not a cell with the specified column name, insert one.
if (row.Elements<Cell>().Where(c => c.CellReference.Value == columnName + rowIndex).Count() > 0)
{
return row.Elements<Cell>().Where(c => c.CellReference.Value == cellReference).First();
}
// Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
Cell refCell = row.Elements<Cell>().FirstOrDefault(cell => string.Compare(cell.CellReference.Value, cellReference, true) > 0);
var newCell = new Cell { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
worksheet.Save();
return newCell;
}
問題已解決。 我對代碼做了一個小改動以使其工作。 而不是在 InsertCellInWorksheet 方法中保存工作表。 我正在將工作表保存在 for 循環之外。 這是代碼的工作版本。
protected void Export()
{
Response.ClearHeaders();
Response.ClearContent();
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
//"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" '"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" '"application/vnd.ms-excel"
Response.AddHeader("content-disposition", "attachment; filename=Test.xlsx");
Response.Charset = "";
this.EnableViewState = false;
MemoryStream ms = new MemoryStream();
SpreadsheetDocument objSpreadsheet = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook);
WorkbookPart objWorkbookPart = objSpreadsheet.AddWorkbookPart();
objWorkbookPart.Workbook = new Workbook();
WorksheetPart objSheetPart = objWorkbookPart.AddNewPart<WorksheetPart>();
objSheetPart.Worksheet = new Worksheet(new SheetData());
Sheets objSheets = objSpreadsheet.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
Sheet objSheet = new Sheet();
objSheet.Id = objSpreadsheet.WorkbookPart.GetIdOfPart(objSheetPart);
objSheet.SheetId = 1;
objSheet.Name = "mySheet";
objSheets.Append(objSheet);
for (int intRow = (int)('A'); intRow <= (int)('Z'); intRow++)
{
for (uint intCol = 1; intCol <= 5; intCol++)
{
Cell objCell = InsertCellInWorksheet(Convert.ToString((char)intRow), intCol, objSheetPart);
objCell.CellValue = new CellValue("This was a test: " + Convert.ToString((char)intRow) + intCol.ToString());
objCell.DataType = new EnumValue<CellValues>(CellValues.String);
}
}
objSheetPart.Worksheet.Save();
objSpreadsheet.WorkbookPart.Workbook.Save();
objSpreadsheet.Close();
ms.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
private static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart)
{
Worksheet worksheet = worksheetPart.Worksheet;
var sheetData = worksheet.GetFirstChild<SheetData>();
string cellReference = columnName + rowIndex;
// If the worksheet does not contain a row with the specified row index, insert one.
Row row;
if (sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex).Count() != 0)
{
row = sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex).First();
}
else
{
row = new Row { RowIndex = rowIndex };
sheetData.Append(row);
}
// If there is not a cell with the specified column name, insert one.
if (row.Elements<Cell>().Where(c => c.CellReference.Value == columnName + rowIndex).Count() > 0)
{
return row.Elements<Cell>().Where(c => c.CellReference.Value == cellReference).First();
}
// Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
Cell refCell = row.Elements<Cell>().FirstOrDefault(cell => string.Compare(cell.CellReference.Value, cellReference, true) > 0);
var newCell = new Cell { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
//worksheet.Save();
return newCell;
}
不確定它在 VB.Net 中是如何工作的 :-)
您所擁有的行和列的循環看起來不正確。 看起來你是從 row = 65 (ie (int)('A') 到 row = 65 + 26 (ie (int)('Z')) 然后 col = 1 到 3 循環。也許你應該從列 = 1 到 5。
我認為您可能需要查看您正在處理的 xml,並確保您正確地瀏覽文檔(行和列)。 如果您不知道,所有 office 2007 和更高版本的文檔都是 openXml 文檔。 它們基本上是包含 xml 的 zip 文件。 如果您使用電子表格並將擴展名從 .xlsx 更改為 .zip,您將能夠將文檔作為 zip 文件打開並瀏覽內容。 我已經一年多沒有使用 openXml,但是如果我沒記錯的話,您會在 sheet 文件夾中找到代表工作表的 xml。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.