簡體   English   中英

OpenXML庫保存Excel文件

[英]OpenXML library save excel file

我有以下代碼,它沒有將值保存到單元格以及文件中。 它在cell.cellvalue字段中顯示值,但未將其寫入excel。 我不知道如何保存文件。 我用的OpenXML SDK和我寫datatable值到每個cell/row創建的電子表格文件。

 using (SpreadsheetDocument ssd=SpreadsheetDocument.Open(Server.MapPath(@"\ExcelPackageTemplate.xlsx"),true))
        {
            WorkbookPart wbPart = ssd.WorkbookPart;
            WorksheetPart worksheetPart = wbPart.WorksheetParts.First();

            SheetData sheetdata = worksheetPart.Worksheet.GetFirstChild<SheetData>();
            string[] headerColumns = new string[] { dt.Columns[0].ColumnName, dt.Columns[1].ColumnName,dt.Columns[2].ColumnName };
            DocumentFormat.OpenXml.Spreadsheet.Row r = new DocumentFormat.OpenXml.Spreadsheet.Row();
            int RowIndexer = 1;
            //int colInd=0;
            r.RowIndex = (UInt32)RowIndexer;

            string test = ColumnName(RowIndexer);

            foreach (DataColumn dc in dt.Columns)
            {

                DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                cell.CellReference = test+RowIndexer;
                cell.DataType = CellValues.InlineString;
                cell.InlineString = new InlineString(new Text(dc.ColumnName.ToString()));
                DocumentFormat.OpenXml.Spreadsheet.CellValue value = new DocumentFormat.OpenXml.Spreadsheet.CellValue();

                r.AppendChild(cell);

                // colInd++;
            }

            //r.RowIndex = (UInt32)RowIndexer;
            RowIndexer = 2;
            foreach (DataRow dr in dt.Rows)
            {
                DocumentFormat.OpenXml.Spreadsheet.Row Row = new DocumentFormat.OpenXml.Spreadsheet.Row();
                string Index = ColumnName(RowIndexer);
                Row.RowIndex = (UInt32)RowIndexer;
                foreach (object value in dr.ItemArray)
                {
                    DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                    cell.DataType = CellValues.InlineString;
                    cell.InlineString =  new InlineString(new Text(value.ToString()));
                    cell.CellReference = Index+RowIndexer;
                   // cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(value.ToString());
                    Row.AppendChild(cell);

                }
                RowIndexer++;

            }

            worksheetPart.Worksheet.Save();
            wbPart.Workbook.Save();
            ssd.Close();

嘗試這個:

using (SpreadsheetDocument ssd = SpreadsheetDocument.Open(Server.MapPath(@"\ExcelPackageTemplate.xlsx"), true))
{
    WorkbookPart wbPart = ssd.WorkbookPart;
    WorksheetPart worksheetPart = wbPart.WorksheetParts.First();

    SheetData sheetdata = worksheetPart.Worksheet.GetFirstChild<SheetData>();
    string[] headerColumns = new string[] { dt.Columns[0].ColumnName, dt.Columns[1].ColumnName, dt.Columns[2].ColumnName };
    DocumentFormat.OpenXml.Spreadsheet.Row r = new DocumentFormat.OpenXml.Spreadsheet.Row();
    DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
    int RowIndexer = 1;
    int ColumnIndexer = 1;

    r.RowIndex = (UInt32)RowIndexer;
    foreach (DataColumn dc in dt.Columns)
    {
        cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
        cell.CellReference = ColumnName(ColumnIndexer) + RowIndexer;
        cell.DataType = CellValues.InlineString;
        cell.InlineString = new InlineString(new Text(dc.ColumnName.ToString()));
        // consider using cell.CellValue. Then you don't need to use InlineString.
        // Because it seems you're not using any rich text so you're just bloating up
        // the XML.

        r.AppendChild(cell);

        ColumnIndexer++;
    }
    // here's the missing part you needed
    sheetdata.Append(r);

    RowIndexer = 2;
    foreach (DataRow dr in dt.Rows)
    {
        r = new DocumentFormat.OpenXml.Spreadsheet.Row();
        r.RowIndex = (UInt32)RowIndexer;
        // this follows the same starting column index as your column header.
        // I'm assuming you start with column 1. Change as you see fit.
        ColumnIndexer = 1;
        foreach (object value in dr.ItemArray)
        {
            cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
            // I moved it here so it's consistent with the above part
            // Also, the original code was using the row index to calculate
            // the column name, which is weird.
            cell.CellReference = ColumnName(ColumnIndexer) + RowIndexer;
            cell.DataType = CellValues.InlineString;
            cell.InlineString = new InlineString(new Text(value.ToString()));

            r.AppendChild(cell);
            ColumnIndexer++;
        }
        RowIndexer++;

        // missing part
        sheetdata.Append(r);
    }

    worksheetPart.Worksheet.Save();
    wbPart.Workbook.Save();
    ssd.Close();
}

一些評論:

  • ColumnName()函數從這里開始
  • 我假設您想要一行中的列標題,以及后續行中的數據(因為原始代碼具有用於計算列名的行索引)。
  • 清理了代碼的某些部分,以便於閱讀,並且列標題和數據行部分的書寫樣式更加一致。
  • 我建議您考慮使用CellValue而不是InlineString。 根據您的代碼,您正在導入一個DataTable,並且您似乎不需要富文本格式,因此InlineString有點過大,可能會使生成的文件更大(XML膨脹)。 使用一個或另一個,並記住相應地設置DataType。
  • 此外,該代碼僅適用於完全空的SheetData。

這里有一些可能的問題:

  • 您創建並添加新的行和單元格:假定打開工作表時該工作表是完全空白的(即:沒有具有相同索引/地址的行或單元格)。

  • 由於將CellType設置為InlineString ,因此需要設置Cell.InlineString而不是Cell.CellValue

     cell.DataType = CellValues.InlineString; cell.InlineString = new InlineString(New Text(value.TsString())); 
  • 另外,您的代碼中有關CellReference用法也有CellReference 這些代碼部分沒有意義:

     cell.CellReference = dc.ColumnName.ToString(); cell.CellReference = value.ToString(); 

    單元地址應類似於“ A1”。 您必須檢查代碼以設置正確的地址。 您已經具有rowIndex。 您需要獲取列名稱。 這樣可以將列索引轉換為Excel列名可以提供幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM