【问题标题】:Export to Excel using Open XML. But Last cell not filling up使用 Open XML 导出到 Excel。但是最后一个单元格没有填满
【发布时间】:2011-07-08 14:21:37
【问题描述】:

我使用this code snippet 使用 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;
}

【问题讨论】:

    标签: c# export-to-excel c#-to-vb.net


    【解决方案1】:

    问题已解决。我对代码做了一些小改动以使其正常工作。而不是将工作表保存在 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 中是如何工作的 :-)

    【讨论】:

      【解决方案2】:

      您所拥有的行和列的循环看起来不正确。看起来您正在从 row = 65 (即 (int)('A') 循环到 row = 65 + 26 (即 (int)('Z'))),然后 col = 1 到 3。 也许您应该从 col = 1 循环到 5。
      我认为您可能需要查看您正在处理的 xml,并确保您正在正确地浏览文档(行和列)。如果您不知道,所有 office 2007 及更高版本的文档都是 openXml 文档。它们基本上是包含 xml 的 zip 文件。如果您使用电子表格并将扩展名从 .xlsx 更改为 .zip,您将能够以 zip 文件的形式打开文档并浏览内容。我已经有一年多没有使用 openXml 了,但是如果我没记错的话,您会在工作表文件夹中找到代表工作表的 xml。

      【讨论】:

      • 感谢您的回复。现在问题已经解决了。请参阅下面的回复以获取答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多