导出到 Excel 时出现错误

Posted

技术标签:

【中文标题】导出到 Excel 时出现错误【英文标题】:I am getting an error while exporting to Excel 【发布时间】:2021-02-25 15:54:36 【问题描述】:

我想将数据从 dataGridView 传输到 Excel。为此,我在我的项目中添加了“Microsoft.Office.Interop.Excel”插件。我正确地编写了必要的代码。但是当我运行项目并单击“导出到 Excel”按钮时,出现错误。我该怎么办?

这是我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DuyuTekStokApp

    public partial class StockAll : Form
    
        SqlConnection connect = new SqlConnection("Data Source=DESKTOP-L01MAVE;Initial Catalog='StockControl';Integrated Security=True");
        public StockAll()
        
            InitializeComponent();
        
        public void VerileriGoster(string Veriler)
        
            SqlDataAdapter da = new SqlDataAdapter(Veriler, connect);
            DataSet ds = new DataSet();
            da.Fill(ds);
            dataGridViewAll.DataSource = ds.Tables[0];
        
        public void changeHeader()
        
            dataGridViewAll.Columns[0].HeaderText = "Stok Kodu";
            dataGridViewAll.Columns[1].HeaderText = "Stok Cinsi";
            dataGridViewAll.Columns[2].HeaderText = "Barkod Numarası";
            dataGridViewAll.Columns[3].HeaderText = "Birimi";
            dataGridViewAll.Columns[4].HeaderText = "Grubu";
            dataGridViewAll.Columns[5].HeaderText = "Tarih";
            dataGridViewAll.Columns[6].HeaderText = "Açıklama";
            dataGridViewAll.Columns[7].HeaderText = "Sınıfı";
            dataGridViewAll.Columns[8].HeaderText = "Değişim Tarihi";
            dataGridViewAll.Columns[9].HeaderText = "Adeti";
            dataGridViewAll.Columns[10].HeaderText = "Kritik Miktar";
            dataGridViewAll.Columns[11].HeaderText = "Resim";
        
        private void StockAll_Load(object sender, EventArgs e)
        
            connect.Open();
            SqlCommand cmd1 = new SqlCommand("SELECT COUNT(*) FROM StockCard", connect);
            SqlDataReader dr1 = cmd1.ExecuteReader();
            while (dr1.Read())
            
                labelToplam.Text = dr1[0].ToString();
            
            connect.Close();

            connect.Open();
            SqlCommand cmd2 = new SqlCommand("SELECT SUM(StokAdet) FROM StockCard", connect);
            SqlDataReader dr2 = cmd2.ExecuteReader();
            while (dr2.Read())
            
                labelGenel.Text = dr2[0].ToString();
            
            connect.Close();

            VerileriGoster("SELECT StokKodu, StokCinsi, StokBarkod, StokBirim, StokGrup, StokTarih, StokAciklama, StokSinif, StokSonTarih, StokAdet, StokKritik, StokResim FROM StockCard ORDER BY StokKodu ASC");
            //VerileriGoster(@"SELECT dbo.StockCard.StokKodu, dbo.StockCard.StokBarkod, dbo.StockCard.StokBirim, dbo.StockCard.StokGrup, dbo.StockCard.StokTarih, dbo.StockCard.StokResim, dbo.StockMove.MoveAdet, dbo.StockMove.MoveMevcut, dbo.StockMove.MoveSinif, dbo.StockMove.MoveTarih
            //                     FROM  dbo.StockMove INNER JOIN
            //                  dbo.StockCard ON dbo.StockMove.StokID = dbo.StockCard.StokID ORDER BY StokKodu ASC ");
            changeHeader();
        

        private void dataGridViewAll_CellClick(object sender, DataGridViewCellEventArgs e)
        
            int secilen = dataGridViewAll.SelectedCells[0].RowIndex;
            labelUrun.Text = dataGridViewAll.Rows[secilen].Cells[9].Value?.ToString();
            labelKrit.Text = dataGridViewAll.Rows[secilen].Cells[10].Value.ToString();
            byte[] bytes = (byte[])dataGridViewAll.Rows[secilen].Cells[11].Value;
            MemoryStream ms = new MemoryStream(bytes);
            pictureBoxResim.Image = Image.FromStream(ms);
        

        private void btnExcel_Click(object sender, EventArgs e)
        
            Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing);
            Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
            worksheet = workbook.Sheets["Sheet1"];
            worksheet = workbook.ActiveSheet;
            worksheet.Name = "Stok Bilgisi";

            for (int i = 1; i < dataGridViewAll.Columns.Count + 1; i++)
            
                worksheet.Cells[i, 1] = dataGridViewAll.Columns[i - 1].HeaderText;
            

            for (int i = 0; i < dataGridViewAll.Rows.Count; i++)
            
                for (int j = 0; j < dataGridViewAll.Columns.Count; i++)
                
                    worksheet.Cells[i + 2, j + 1] = dataGridViewAll.Rows[i].Cells[j].Value.ToString();
                
            

            var saveFileDialog = new SaveFileDialog();
            saveFileDialog.FileName = "StokBilgisi";
            saveFileDialog.DefaultExt = ".xlsx";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            
                workbook.SaveAs(saveFileDialog.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            
            app.Quit();

            
        
    

这是我收到的错误消息:

System.InvalidCastException
  HResult = 0x80004002
  Message = COM object of type 'Microsoft.Office.Interop.Excel.ApplicationClass' could not be assigned to interface type 'Microsoft.Office.Interop.Excel._Application'. This operation failed because the QueryInterface call on the COM component for the interface with the IID '000208D5-0000-0000-C000-000000000046' failed with the following error: Error loading type library / DLL. (HRESULT returned exception: 0x80029C4A (TYPE_E_CANTLOADLIBRARY)).
  Source = mscorlib
  StackTrace:
   at System.StubHelpers.StubHelpers.GetCOMIPFromRCW (Object objSrc, IntPtr pCPCMD, IntPtr & ppTarget, Boolean & pfNeedsRelease)
   at Microsoft.Office.Interop.Excel.ApplicationClass.get_Workbooks ()
   at SenseTekStokApp.StockAll.btnExcel_Click (Object sender, EventArgs e) in D: \ yNs \ VisualTutorials \ SenseTekStokApp \ SenseTekStokApp \ StockAll.cs: line 84
   at System.Windows.Forms.Control.OnClick (EventArgs e)
   at System.Windows.Forms.Button.OnClick (EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp (MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp (Message & m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc (Message & m)
   at System.Windows.Forms.ButtonBase.WndProc (Message & m)
   at System.Windows.Forms.Button.WndProc (Message & m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage (Message & m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc (Message & m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback (IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW (MSG & msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop (IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner (Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop (Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run (Form mainForm)
   at SenseTekStokApp.Program.Main () in D: \ yNs \ VisualTutorials \ SenseTekStokApp \ SenseTekStokApp \ Program.cs: line 19

【问题讨论】:

这能回答你的问题吗? Unable to cast COM object of type 'Microsoft.Office.Interop.Excel.ApplicationClass' to interface type 'Microsoft.Office.Interop.Excel._Application' 有很多库可以为你编写 XLSX 文件。不推荐使用 Interop。 不,不要使用互操作。您已经将数据下载到数据表中,因此很容易通过数据绑定在网格中显示,并且很容易(几行代码)使用 EPPlus 之类的东西写入 excel 文件。 例如***.com/questions/13669733/… 明白。我会尝试 EPPlus。如果它以我想要的方式发生,我会在这里说出来。 【参考方案1】:

您可以尝试以下步骤将datagirdview转换为excel。

首先,请安装nuget-packageMicrosoft.Office.Interop.Excel

其次,请在代码中使用。

using Excel=Microsoft.Office.Interop.Excel;

第三,我建议你可以先把datagirdview转成datatable,然后再把datatable转成excel。

private void button1_Click(object sender, EventArgs e)
        
            DataTable table = (DataTable)dataGridView1.DataSource;
            ExportToExcel(table);
        

 public void ExportToExcel(DataTable tbl )
        
            try
            
                if (tbl == null || tbl.Columns.Count == 0)
                    throw new Exception("ExportToExcel: Null or empty input table!\n");

                // load excel, and create a new workbook
                var excelApp = new Excel.Application();
                var workbook=excelApp.Workbooks.Add();

                // single worksheet
                Excel._Worksheet workSheet = excelApp.ActiveSheet;

                // column headings
                for (var i = 0; i < tbl.Columns.Count; i++)
                
                    workSheet.Cells[1, i + 1] = tbl.Columns[i].ColumnName;
                

                // rows
                for (var i = 0; i < tbl.Rows.Count; i++)
                
                    // to do: format datetime values before printing
                    for (var j = 0; j < tbl.Columns.Count; j++)
                    
                        workSheet.Cells[i + 2, j + 1] = tbl.Rows[i][j];
                    
                

                try
                
                    var saveFileDialog = new SaveFileDialog();
                    saveFileDialog.FileName = "StokBilgisi";
                    saveFileDialog.DefaultExt = ".xlsx";
                    if (saveFileDialog.ShowDialog() == DialogResult.OK)
                    
                        workbook.SaveAs(saveFileDialog.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                    
                    excelApp.Quit();
                    Console.WriteLine("Excel file saved!");
                
                catch (Exception ex)
                
                    throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n"
                    + ex.Message);
                

            
            catch (Exception ex)
            
                throw new Exception("ExportToExcel: \n" + ex.Message);
            
        

【讨论】:

这场婚礼不知何故成功了。但是当我点击按钮时,我得到了一个错误。 “System.Exception HResult = 0x80131500 Message = ExportToExcel: HRESULT 返回异常:0x800A03EC”给出了这个错误。会不会是我电脑上安装的“Excel”有问题? @YunusEmreSöğüt,根据我的研究,您可以检查您的文件是否以 xlsx 结尾。如果不是,请将其更改为 test.xlsx。 @YunusEmreSöğüt,您可以接受它作为答案,以便其他人可以解决类似的问题。【参考方案2】:

本质上,使用 EPPlus(每 cmets)将您的网格保存到 excel 文件:


private void btnExcel_Click(object sender, EventArgs e)

  var saveFileDialog = new SaveFileDialog();
  saveFileDialog.FileName = "StokBilgisi";
  saveFileDialog.DefaultExt = ".xlsx";
  if (saveFileDialog.ShowDialog() == DialogResult.OK)
  

    using (ExcelPackage pck = new ExcelPackage(new FileInfo(saveFileDialog.FileName)))
    
      ExcelWorksheet ws = pck.Workbook.Worksheets.Add("StokBilgisi");
      ws.Cells["A1"].LoadFromDataTable(dataGridViewAll.DataSource as DataTable, true);
      pck.Save();
    
  

这是the code from the linked question/answer,通过插入dataGridViewAll.DataSource as DataTable 来根据您的上下文进行调整,以检索您在VerileriGoster 中调用dataGridViewAll.DataSource = ds.Tables[0]; 时绑定到网格的数据表,以及其他一些问题,例如选择要保存的文件名一个保存文件对话框

【讨论】:

首先,谢谢。我试过这个,但是“(ExcelPackage pck = new ExcelPackage(saveFileDialog.FileName))”这里“(saveFileDialog.Filename)”给出了一个错误。参数 1: cannot convert from 'string' to 'System.IO.FileInfo' 给出错误。 我总是忘记的一件事是 EPPlus 采用 FileInfo,而不是字符串文件路径。只需将其更改为new ExcelPackage (new FileInfo(saveFileDialog.FileName)) 并记住using System.IO 这次成功了。我点击了按钮,文件选择部分出现了。当我说保存时,我得到了另一个错误。我认为这与 EPPlus 许可证有关。 OfficeOpenXml.LicenseException HResult = 0x80131500 消息 = 请设置 ExcelPackage.LicenseContext 属性。见epplussoftware.com/developers/licenseexception ...这样的错误。我尝试了一些东西,但做不到。我该如何解决? 我安装了一个较早的版本,它已被修复。现在一切都按我想要的方式顺利进行。谢谢你为我做的一切。 :) 如果您阅读该文档,它基本上会说“阅读许可证,如果您的使用意味着您必须付费,则付款并设置 Licensed = true,如果您的使用意味着您没有支付,然后设置 Licensed=true".. 你做什么取决于你和你的道德指南针,但实际上,如果你在应该付费(商业)的环境中使用这个软件,它不会是你的口袋无论如何资助它。开发人员做得很棒,所以他们应得的钱(就像任何为钱工作的人一样)所以如果你应该付钱的话。或者您可以使用许可不同的 v4

以上是关于导出到 Excel 时出现错误的主要内容,如果未能解决你的问题,请参考以下文章

将 dataGridView 数据导出到 excel 时出现错误

使用 EPPlus 库从 SQL Server 导出到 Excel 时出现“内存不足”异常

将 Excel 工作表导出到 PDF 文件时出现奇怪的 Powershell 行为

php 从Gravity Forms导出文件中删除空行(导入到excel时出现问题)

Java用POI导出excel时出现内存不足的问题,测试数据数量为:13万条,已经实现了,每六万条条数据时

如何导出到Excel?