使用Open XML导出到Excel。但最后一个细胞没有填满

时间:2011-03-04 06:04:08

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

我使用以下链接中的代码使用Open XML将数据导出到Excel。

http://openxmldeveloper.org/forums/permalink/123327/8373/ShowThread.aspx#8373

代码在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;
}

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

通过您拥有的行和列的循环看起来不正确。看起来你是从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代表了sheet文件夹中的工作表。