繁体   English   中英

使用 Open XML 导出到 Excel。 但最后一个单元格没有填满

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM