DataGridViewS导出到excell工作表

时间:2019-11-26 12:52:04

标签: c# excel winforms datagridview excellibrary

我想在一个Excell文档中导出所有DataGridView。 对于每个DataGridView,Excell文件中都应该有自己的工作表。

但是使用我的代码,我只收到错误:System.Runtime.InteropServices.COMException:HRESULT:0x800A03EC“

我认为我的参数有问题。

        private void exportToExcellButton_Click(object sender, EventArgs e)
    {
        SaveFileDialog saveFileD = new SaveFileDialog();
        string fileName = truckListBox.SelectedItem.ToString() + "__" + DateTime.Now.ToShortDateString();
        saveFileD.InitialDirectory = @"C:/TML/";
        saveFileD.FileName = fileName;

        if (!Directory.Exists(@"C:/TML/"))

            Directory.CreateDirectory(@"C:/TML/");

        List<DataGridView> dataGridViews = getAllDataGridViews();

        Microsoft.Office.Interop.Excel.Application app;
        Microsoft.Office.Interop.Excel.Workbook book;
        Microsoft.Office.Interop.Excel.Worksheet sheet;

        app = new Excel.Application();
        app.Visible = true;
        book = app.Workbooks.Add(System.Reflection.Missing.Value);

        foreach (var grid in dataGridViews)
        {
          int count = book.Worksheets.Count;
          sheet = (Worksheet)book.Sheets.Add(Type.Missing, book.Worksheets[count], Type.Missing, Type.Missing);
            sheet.Name = grid.Name.ToString().Remove(0, 13);

            int cMin = 0, rMin = 0;
            int c = cMin, r = rMin;

            // Set Headers
            foreach (DataGridViewColumn column in grid.Columns)
            {
            //Here appears the Error: System.Runtime.InteropServices.COMException: HRESULT: 0x800A03EC"
                sheet.Cells[r, c] = column.HeaderText;
                c++;
            }

            sheet.Range[sheet.Cells[r, cMin], sheet.Cells[r, c]].Font.Bold = true;
            sheet.Range[sheet.Cells[r, cMin], sheet.Cells[r, c]].VerticalAlignment = Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;

            // Set Rows
            foreach (DataGridViewRow row in grid.Rows)
            {
                r++;
                c = cMin;
                // Set Cells
                foreach (DataGridViewCell item in row.Cells)
                {
                    sheet.Cells[r, c++] = item.Value;
                }
            }
        }
        book.Save();
        book.Close();
        app.Quit();
    }

花了所有准备时间,无法正常工作。 谢谢您的帮助!

编辑:修复了一种错误,以获取新的错误。

2 个答案:

答案 0 :(得分:1)

发布的代码可能存在一些问题。因此,我将它们分解。

对于初学者来说,您似乎正在使用SaveFileDialog,但是我看不到它的使用位置。该代码设置了InitalDirectoryFileName,但从未使用过。这并不是很重要,因为实际上并不需要对话框,但是代码获取文件名的方式会遇到一些问题。代码行…

string fileName = truckListBox.SelectedItem.ToString() + "__" + DateTime.Now.ToShortDateString();
如果您尝试保存文件名,

将会出现问题,因为从DateTime.Now.ToShortDateString()返回的字符串将采用类似“ 2019 \ 11 \ 26”的格式。显然,“ \”字符将被解释为路径(文件夹),并且在代码尝试保存文件时最有可能失败。创建返回一个使用其他字符的字符串的方法应该很容易解决。

接下来的事实是,Excel文件基于其行和列不为零。因此,首次尝试设置Excel初始行列变量(int c = 0, r = 0;)将失败。这些值应为一(1)。

另一个问题就在线上……

book.Save();

最有可能使用文件名“ Book1.xlsx”将文件保存到用户“ Documents”文件夹。保存文件时,您需要提供完整的路径和文件名,如前所述,该路径和文件名不会出现使用。

最后,每当您使用“ COM”对象(例如Excel应用程序,工作簿和工作表)时,代码在退出程序之前“释放”代码创建的com对象非常重要。在当前发布的代码中,很有可能仍在运行着挥之不去的“ Excel”资源。因此,为避免资源泄漏,对于您的代码而言,释放其创建的com对象很重要。 在下面的示例中,释放资源的代码位于finally语句的try/catch/finally子句中。

private void button1_Click(object sender, EventArgs e) {
  //SaveFileDialog saveFileD = new SaveFileDialog();
  //string fileName = truckListBox.SelectedItem.ToString() + "__" + DateTime.Now.ToShortDateString();
  string fileName = @"C:\Users\John\Desktop\Grr\TestExcelFile" + "__" + DateTime.Now.Year + "_" + DateTime.Now.Month;

  //saveFileD.InitialDirectory = @"C:\Users\John\Desktop\Grr\";
  //saveFileD.FileName = fileName;

  //if (!Directory.Exists(@"C:/TML/"))

  //    Directory.CreateDirectory(@"C:/TML/");

  //List<DataGridView> dataGridViews = getAllDataGridViews();
  List<DataGridView> dataGridViews = getGrids();

  Microsoft.Office.Interop.Excel.Application app = null;
  Microsoft.Office.Interop.Excel.Workbook book = null;
  Microsoft.Office.Interop.Excel.Worksheet sheet = null;

  app = new Microsoft.Office.Interop.Excel.Application();
  app.Visible = true;
  book = app.Workbooks.Add(System.Reflection.Missing.Value);
  try {
    foreach (var grid in dataGridViews) {
      int count = book.Worksheets.Count;
      //sheet = (Microsoft.Office.Interop.Excel.Worksheet)book.Sheets.Add(Type.Missing, book.Worksheets[count], Type.Missing, Type.Missing);
      sheet = (Microsoft.Office.Interop.Excel.Worksheet)book.Worksheets.Add();
      //sheet.Name = grid.Name.ToString().Remove(0, 13);
      sheet.Name = grid.Name.ToString();

      int cMin = 1, rMin = 1;
      int c = cMin, r = rMin;

      // Set Headers
      foreach (DataGridViewColumn column in grid.Columns) {
        //Here appears the Error: System.Runtime.InteropServices.COMException: HRESULT: 0x800A03EC"
        sheet.Cells[r, c] = column.HeaderText;
        c++;
      }

      sheet.Range[sheet.Cells[r, cMin], sheet.Cells[r, c]].Font.Bold = true;
      sheet.Range[sheet.Cells[r, cMin], sheet.Cells[r, c]].VerticalAlignment = Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;

      // Set Rows
      foreach (DataGridViewRow row in grid.Rows) {
        r++;
        c = cMin;
        // Set Cells
        foreach (DataGridViewCell item in row.Cells) {
          sheet.Cells[r, c++] = item.Value;
        }
      }
    }
    book.SaveAs(fileName, Type.Missing, Type.Missing, Type.Missing);
    book.Close();
    app.Quit();
  }
  catch (Exception ex) {
    MessageBox.Show("Error writing to excel: " + ex.Message);
  }
  finally {
    if (sheet != null)
      Marshal.ReleaseComObject(sheet);
    if (book != null)
      Marshal.ReleaseComObject(book);
    if (app != null)
      Marshal.ReleaseComObject(app);
  }
}

希望这会有所帮助。

答案 1 :(得分:0)

只需创建一个方法并传递DataGridView

using Excel = Microsoft.Office.Interop.Excel;
public void ete(DataGridView dgv)//ExportToExcel
    {
        // Creating a Excel object.

        Excel._Application excel = new Excel.Application();
        Excel._Workbook workbook = excel.Workbooks.Add(Type.Missing);
        Excel._Worksheet worksheet = null;
        excel.Columns.ColumnWidth = 20;

        try
        {

            worksheet = workbook.ActiveSheet;

            worksheet.Name = "ExportedFromDatGrid";

            int cellRowIndex = 1;
            int cellColumnIndex = 1;

            //Loop through each row and read value from each column.
            for (int i = -1; i < dgv.Rows.Count; i++)
            {
                for (int j = 0; j < dgv.Columns.Count; j++)
                {
                    // Excel index starts from 1,1. As first Row would have the Column headers, adding a condition check.
                    if (cellRowIndex == 1)
                    {
                        worksheet.Cells[cellRowIndex, cellColumnIndex] = dgv.Columns[j].HeaderText;
                    }
                    else
                    {
                        worksheet.Cells[cellRowIndex, cellColumnIndex] = dgv.Rows[i].Cells[j].Value.ToString();
                    }
                    cellColumnIndex++;
                }
                cellColumnIndex = 1;
                cellRowIndex++;
            }

            //Getting the location and file name of the excel to save from user.
            SaveFileDialog saveDialog = new SaveFileDialog();
            saveDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
            saveDialog.FilterIndex = 2;

            if (saveDialog.ShowDialog() == DialogResult.OK)
            {
                workbook.SaveAs(saveDialog.FileName.ToString());
                MessageBox.Show("Export Successful");
            }
        }
        catch (System.Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {
            excel.Quit();
            workbook = null;
            excel = null;
        }

    }

立即调用方法

ete(datagridview1);