【问题标题】:Update existing excel sheet with openxml and C#使用 openxml 和 C# 更新现有的 Excel 工作表
【发布时间】:2018-12-20 18:52:03
【问题描述】:

我需要将大量数据从数据库导出到 Excel。我创建了一种从选择中导出数据的方法..但我设法创建了一个新的 excel。不更新现有的。我在互联网上搜索过,但我不明白我做错了什么。

这是我的方法代码:

public static void ExportDSToExcel(DataSet ds, string destination)
    {
        using (var workbook = SpreadsheetDocument.Open(destination, true))
        {
            //var workbookPart = workbook.AddWorkbookPart();
            workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
            workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets();

            uint sheetId = 1;

            foreach (DataTable table in ds.Tables)
            {
                var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
                var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
                sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);

                DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
                string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);

                if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0)
                {
                    sheetId =
                        sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
                }

                DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName };
                sheets.Append(sheet);

                DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row();

                List<String> columns = new List<string>();
                foreach (DataColumn column in table.Columns)
                {
                    columns.Add(column.ColumnName);

                    DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                    cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
                    cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName);
                    headerRow.AppendChild(cell);
                }

                sheetData.AppendChild(headerRow);

                foreach (DataRow dsrow in table.Rows)
                {
                    DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
                    foreach (String col in columns)
                    {
                        DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                        cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
                        cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); //
                        newRow.AppendChild(cell);
                    }

                    sheetData.AppendChild(newRow);
                }
            }

这里是我调用方法的地方:

string _oracleConnection = "Data Source=XXXXX;Persist Security Info=True;User ID=XXXXXX;Password=YYYYY";

        OracleConnection con = new OracleConnection(_oracleConnection);
        using (con = new OracleConnection(_oracleConnection))
        {
            using (OracleCommand cmd = new OracleCommand())
            {
                cmd.Connection = con;
                cmd.CommandType = CommandType.Text;

                 cmd.CommandText = "SELECT connect_by_root proj_catg_name, parent_proj_catg_id,LTRIM(SYS_CONNECT_BY_PATH (proj_catg_short_name, '-'),'-') id_path, proj_catg_name FROM pcatval start with  proj_catg_name in ('XXXXXXXXXXXXX', 'XXXXXXXXXXXXXX') CONNECT BY PRIOR proj_catg_id = parent_proj_catg_id ";

                con.Open();
                DataSet ds = new System.Data.DataSet();
                OracleDataAdapter oda = new OracleDataAdapter(cmd);
                oda.Fill(ds);
                string destination = @"D:\TEST.xlsx";
                P_IAP.Excelfile.ExportDSToExcel(ds, destination);
            }

            Excelfile excelfile = new Excelfile();

你知道我应该改变什么吗?假设我想更新一个名为 TEST 的 Excel 文件和名为 Sheet1 的工作表

【问题讨论】:

  • 请帮助我理解我做错了什么..
  • 能否请您发布正确和完整的代码以检查错误的部分?
  • 我添加了我的代码..以及我调用该方法的那个

标签: c# excel openxml


【解决方案1】:

要通过 OpenXml 修改 Excel 文件并再次保存,您应该使用它的 stream 打开它:

byte[] ByteArrayContent = File.ReadAllBytes(path);
using (MemoryStream mStream = new MemoryStream())
{
    stream.Write(ByteArrayContent , 0, (int)ByteArrayContent .Length);
    using (SpreadsheetDocument workbook = SpreadsheetDocument.Open(mStream , true))
    {
       uint sheetId = 1;

        foreach (DataTable table in ds.Tables)
        {
            var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
            var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
            sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);

            DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
            string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);

            if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0)
            {
                sheetId =
                    sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
            }

            DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName };
            sheets.Append(sheet);

            DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row();

            List<String> columns = new List<string>();
            foreach (DataColumn column in table.Columns)
            {
                columns.Add(column.ColumnName);

                DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
                cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName);
                headerRow.AppendChild(cell);
            }

            sheetData.AppendChild(headerRow);

            foreach (DataRow dsrow in table.Rows)
            {
                DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
                foreach (String col in columns)
                {
                    DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                    cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
                    cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); //
                    newRow.AppendChild(cell);
                }

                sheetData.AppendChild(newRow);
            }
        }
    }
    File.WriteAllBytes(SaveAsPath, mStream.ToArray()); 
}

它还回复了here

【讨论】:

  • 它不工作。我的意思是..我复制你的例子并将我的代码放在休息区..没有任何反应
  • 如果生成了新文件,那么问题是,您应该保存 OpenXml 所做的更改。我想你的 sheetnewRow 应该有一个名为 save() 的方法。在使用流保存之前,您应该调用 save()
  • File.WriteAllBytes(SaveAsPath, mStream.ToArray()); 之后是否生成了新文件?
  • 我不明白我应该如何使用您的示例..因为它们非常不同。我是这个 openxml 的新手..
  • 我的代码的想法不是从它的路径访问excel文件,而是通过流访问它,所以不是将目标传递给SpreadsheetDocument.Open(destination, true)),而是从内存流中获取字节并将mStream 传递给你的代码就像SpreadsheetDocument.Open(mStream, true))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多