关于winfrom中如何快速导出DataGridView数据到excel中的问题

这两天一直在写一个售后服务的项目,其中有一个功能是导出DataGridView的数据到Excel中,期间尝试了很多种方法导出,结果都不是很理想,不是速度非常慢就是很卡,导出一个一千多行的数据结果需要5 6分钟,这当然是用户不可能接受的,所以经过我反复测试,发现了一个快速导出的好方法,在此分享出来。以下是常规的方法,最后一个是最快的方法。

常规的VB方法,虽然代码量少,但是不太理想,比如导出时间很慢。

  Function LeadToExcel(ByVal dgv As DataGridView) As Boolean    '导出为Excel函数
        '建立Excel连接
        ' Dim myExcel As Excel.Application = New Microsoft.Office.Interop.Excel.Application()
        Dim myExcel = CreateObject("Excel.Application")
        myExcel.Application.Workbooks.Add(True)
        myExcel.Visible = True
        '定义循环变量,行,列变量
        Dim intRow As Integer
        Dim intColumn As Integer
        Dim intTitle As Integer
        '添加表头
        For intTitle = 0 To dgv.ColumnCount - 1
            myExcel.Cells(1, intTitle + 1) = dgv.Columns(intTitle).HeaderText
        Next intTitle
        For intRow = 0 To dgv.RowCount - 1
            For intColumn = 0 To dgv.ColumnCount - 1
                '由于第一行是表头,所以添加数据时:
                'Excel中从第二行,第一列(2,1)开始赋值,
                'DataGridView从第一行,第一列(0,0)开始赋值(index 从0,0开始)
                myExcel.Cells(intRow + 2, intColumn + 1) = dgv(intColumn, intRow).Value.ToString
            Next intColumn
        Next intRow
        Return True     '添加完毕,返回true
    End Function

用流的方式导出,虽然也比较快,但是导出的文件总是提示,格式不正确,但依然能打开,只是编辑后只能另存为。

 Private Sub btnExport_Click(sender As Object, e As EventArgs) Handles btnExport.Click
        Try
            Dim path As String = ""
            Dim saveDialog As SaveFileDialog = New SaveFileDialog()
            saveDialog.DefaultExt = ".xls"
            saveDialog.Filter = "Excel File(*.xls)|*.xlsx|All Files(*.*)|*.*"
            Dim DR As DialogResult = saveDialog.ShowDialog()
            path = saveDialog.FileName
            If DR = DialogResult.OK Then
                Dim sw As StreamWriter = New StreamWriter(path, False, Encoding.UTF8)
                Dim sb As StringBuilder = New StringBuilder()
                For k = 0 To DataGridView_Report.ColumnCount - 1 Step 1
                    If DataGridView_Report.Columns(k).Visible = True Then
                        sb.Append(DataGridView_Report.Columns(k).HeaderText.ToString.Trim() & "," & vbTab)
                    End If
                Next
                sb.Append(Environment.NewLine)
                For i = 0 To DataGridView_Report.Rows.Count - 2 Step 1
                    System.Windows.Forms.Application.DoEvents()
                    For j = 0 To DataGridView_Report.Columns.Count - 1 Step 1
                        If DataGridView_Report.Columns(j).Visible = True Then
                            sb.Append(DataGridView_Report.Rows(i).Cells(j).Value.ToString.Trim() & "," & vbTab)
                            If j = DataGridView_Report.Columns.Count - 1 Then
                                sb.Append(Environment.NewLine)
                            End If
                        End If
                    Next
                Next
                sb.Append(Environment.NewLine)
                sw.Write(sb.ToString())
                sw.Flush()
                sw.Close()
                MessageBox.Show(path + ",导出成功", "系统提示", MessageBoxButtons.OK)
            Else
                Exit Sub
            End If
        Catch ex As Exception
            MsgBox("错误信息:" + ex.Message, MsgBoxStyle.OkOnly + MsgBoxStyle.Exclamation, "提示")
        End Try
        End Su

用VB代码实现快速导出DataGridView数据到Excel
需要引用这两个库Microsoft.Office.Interop.Excel 、Microsoft Office 15.0 Object Library

Imports Microsoft.Office.Core
Imports Microsoft.Office.Interop.Excel
Imports System.IO
Imports System.Collections
Imports System.Reflection
  Public Sub DataToExcelFast(dgv As DataGridView, fName As String)
        Try
            Dim excel As New Microsoft.Office.Interop.Excel.Application()
            Dim wb As Microsoft.Office.Interop.Excel.Workbook = excel.Workbooks.Add(True)
            Dim ws As Microsoft.Office.Interop.Excel.Worksheet = DirectCast(wb.ActiveSheet, Microsoft.Office.Interop.Excel.Worksheet)
            ws.Name = fName
            Dim sFile As String = String.Empty
            Dim dialog As New SaveFileDialog()
            dialog.Title = "Save export file"
            dialog.Filter = "EXECL File(*.xlsx) |.xlsx"
            dialog.FileName = fName
            dialog.FilterIndex = 1
            If dialog.ShowDialog() = DialogResult.OK Then
                Dim FileName As String = dialog.FileName
                If File.Exists(FileName) Then
                    File.Delete(FileName)
                End If
                sFile = FileName
                excel.Visible = False
                excel.DisplayAlerts = False
                excel.Calculation = Microsoft.Office.Interop.Excel.XlCalculation.xlCalculationManual
                Dim cols As New System.Collections.ArrayList()
                '#Region "列标题,并根据列的数据类型设置Excel列的格式"
                Dim visibleColumnCount As Integer = 0
                For Each col As DataGridViewColumn In dgv.Columns
                    If col.Visible Then
                        visibleColumnCount += 1
                        ws.Cells(1, visibleColumnCount).Value2 = col.HeaderText.ToString()
                        ws.Cells(1, visibleColumnCount).Font.Bold = True
                        cols.Add(col.Name)
                        If col.ValueType IsNot Nothing Then
                            If col.ValueType.Name.Equals("DateTime") Then

                                ws.Columns(visibleColumnCount).NumberFormatLocal = "yyyy-mm-dd HH:mm"
                            ElseIf col.ValueType.Name.Equals("Decimal") OrElse col.ValueType.Name.Equals("Double") Then
                                ws.Columns(visibleColumnCount).NumberFormat = "0.00"
                            ElseIf col.ValueType.Name.Equals("Int32") Then
                                ws.Columns(visibleColumnCount).NumberFormat = "0"
                            Else
                                ws.Columns(visibleColumnCount).NumberFormatLocal = "@"
                            End If
                        Else
                            ws.Columns(visibleColumnCount).NumberFormatLocal = "@"
                        End If
                    End If
                Next
                '#End Region
                '#Region "写入行"
                ' Copy each DataTable  
                ' Copy the DataTable to an object array  
                Dim rawData As Object(,) = New Object(dgv.Rows.Count - 1, cols.Count - 1) {}

                ' Copy the column names to the first row of the object array  
                For col As Integer = 0 To cols.Count - 1
                    rawData(0, col) = cols(col)
                Next
                ' Copy the values to the object array  
                For col As Integer = 0 To cols.Count - 1
                    For row As Integer = 0 To dgv.Rows.Count - 1
                        rawData(row, col) = dgv.Rows(row).Cells(cols(col).ToString()).Value
                    Next
                Next
                ' Calculate the final column letter  
                Dim finalColLetter As String = String.Empty
                Dim colCharset As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                Dim colCharsetLen As Integer = colCharset.Length
                If cols.Count > colCharsetLen Then
                    finalColLetter = colCharset.Substring((cols.Count - 1) / colCharsetLen - 1, 1)
                End If
                finalColLetter += colCharset.Substring((cols.Count - 1) Mod colCharsetLen, 1)
                ' Fast data export to Excel  
                Dim excelRange As String = String.Format("A2:{0}{1}", finalColLetter, dgv.Rows.Count + 1)
                ws.Range(excelRange, Type.Missing).Value2 = rawData
                '#End Region
                excel.Calculation = Microsoft.Office.Interop.Excel.XlCalculation.xlCalculationAutomatic
                ' 51表示2007-2010格式的xlsx  
                ws.SaveAs(FileName, 51, Type.Missing, Type.Missing, Type.Missing, Type.Missing, _
                    Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing)
                wb.Close(True, Type.Missing, Type.Missing)
                excel.Quit()
                ' 安全回收进程  
                System.GC.GetGeneration(excel)
                If MessageBox.Show("数据已导出成功,是否需要打开文件?", "提示", MessageBoxButtons.YesNo) = DialogResult.Yes Then
                    System.Diagnostics.Process.Start(FileName)
                End If
            End If
        Catch ex As Exception
            MessageBox.Show("导出数据异常" & vbCr & vbLf + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.[Error])
        End Try
    End Sub

以下是C#实现快速导出DataGridView数据到Excel的代码
需要引用这两个库Microsoft.Office.Interop.Excel 、Microsoft Office 15.0 Object Library

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Forms;
namespace TextExportCshap
{
    class ExportDataGridView
    {
        public void DataToExcelFast(DataGridView dgv, string fName)
        {
            try
            {
                Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
                Microsoft.Office.Interop.Excel.Workbook wb = excel.Workbooks.Add(true);
                Microsoft.Office.Interop.Excel.Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.ActiveSheet;
                ws.Name = fName;
                string sFile = string.Empty;
                SaveFileDialog dialog = new SaveFileDialog();
                dialog.Title = "Save export file";
                dialog.Filter = "EXECL File(*.xlsx) |.xlsx";
                dialog.FileName = fName;
                dialog.FilterIndex = 1;
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    string FileName = dialog.FileName;
                    if (File.Exists(FileName))
                        File.Delete(FileName);
                    sFile = FileName;
                    excel.Visible = false;
                    excel.DisplayAlerts = false;
                    excel.Calculation = Microsoft.Office.Interop.Excel.XlCalculation.xlCalculationManual;
                    System.Collections.ArrayList cols = new System.Collections.ArrayList();
                    #region 列标题,并根据列的数据类型设置Excel列的格式
                    int visibleColumnCount = 0;
                    foreach (DataGridViewColumn col in dgv.Columns)
                    {
                        if (col.Visible)
                        {
                            visibleColumnCount++;
                            ws.Cells[1, visibleColumnCount].Value2 = col.HeaderText.ToString();
                            ws.Cells[1, visibleColumnCount].Font.Bold = true;
                            cols.Add(col.Name);
                            if (col.ValueType != null)
                            {
                                if (col.ValueType.Name.Equals("DateTime"))
                                {
                                    ws.Columns[visibleColumnCount].NumberFormatLocal = @"yyyy-mm-dd HH:mm";
                                   
                                }
                                else if (col.ValueType.Name.Equals("Decimal")
                                    || col.ValueType.Name.Equals("Double"))
                                {
                                    ws.Columns[visibleColumnCount].NumberFormat = "0.00";
                                }
                                else if (col.ValueType.Name.Equals("Int32"))
                                {
                                    ws.Columns[visibleColumnCount].NumberFormat = "0";
                                }
                                else
                                {
                                    ws.Columns[visibleColumnCount].NumberFormatLocal = @"@";
                                }
                            }
                            else
                                ws.Columns[visibleColumnCount].NumberFormatLocal = @"@";
                        }
                    }
                    #endregion
                    #region 写入行
                    // Copy each DataTable  
                    // Copy the DataTable to an object array  
                    object[,] rawData = new object[dgv.Rows.Count, cols.Count];

                    // Copy the column names to the first row of the object array  
                    for (int col = 0; col < cols.Count; col++)
                    {
                        rawData[0, col] = cols[col];
                    }
                    // Copy the values to the object array  
                    for (int col = 0; col < cols.Count; col++)
                    {
                        for (int row = 0; row < dgv.Rows.Count; row++)
                        {
                            rawData[row, col] = dgv.Rows[row].Cells[cols[col].ToString()].Value;
                        }
                    }
                    // Calculate the final column letter  
                    string finalColLetter = string.Empty;
                    string colCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
                    int colCharsetLen = colCharset.Length;
                    if (cols.Count > colCharsetLen)
                    {
                        finalColLetter = colCharset.Substring(
                            (cols.Count - 1) / colCharsetLen - 1, 1);
                    }
                    finalColLetter += colCharset.Substring(
                            (cols.Count - 1) % colCharsetLen, 1);
                    // Fast data export to Excel  
                    string excelRange = string.Format("A2:{0}{1}",
                        finalColLetter, dgv.Rows.Count + 1);
                    ws.get_Range(excelRange, Type.Missing).Value2 = rawData;
                    #endregion
                    excel.Calculation = Microsoft.Office.Interop.Excel.XlCalculation.xlCalculationAutomatic;
                    // 51表示2007-2010格式的xlsx  
                    ws.SaveAs(FileName, 51, Type.Missing, Type.Missing,
                        Type.Missing, Type.Missing,
                        Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
                        Type.Missing, Type.Missing, Type.Missing);
                    wb.Close(true, Type.Missing, Type.Missing);
                    excel.Quit();
                    // 安全回收进程  
                    System.GC.GetGeneration(excel);
                    if (MessageBox.Show("数据已导出成功,是否需要打开文件?", "提示",
                         MessageBoxButtons.YesNo) == DialogResult.Yes)
                        System.Diagnostics.Process.Start(FileName);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("导出数据异常\r\n" + ex.Message,
                "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 Winform ,你可以使用 NPOI 类库来实现数据导出,具体操作步骤如下: 1. 首先,你需要在项目添加 NPOI 的引用。可以通过 NuGet 包管理器来安装 NPOI。 2. 创建一个 Workbook 对象,用于创建 Excel 文件并设置其属性。 ```csharp HSSFWorkbook workbook = new HSSFWorkbook(); //创建一个 Excel 文件 HSSFSheet sheet = workbook.CreateSheet("Sheet1"); //创建一个工作表 ``` 3. 创建表头信息,并将其写入到 Excel 文件。 ```csharp HSSFRow headerRow = sheet.CreateRow(0); //创建表头行 //设置表头信息 headerRow.CreateCell(0).SetCellValue("姓名"); headerRow.CreateCell(1).SetCellValue("年龄"); headerRow.CreateCell(2).SetCellValue("性别"); ``` 4. 遍历数据源,将数据写入到 Excel 文件。 ```csharp for (int i = 0; i < dataSource.Length; i++) { HSSFRow dataRow = sheet.CreateRow(i + 1); //创建数据行 //设置数据信息 dataRow.CreateCell(0).SetCellValue(dataSource[i].Name); dataRow.CreateCell(1).SetCellValue(dataSource[i].Age); dataRow.CreateCell(2).SetCellValue(dataSource[i].Gender); } ``` 5. 将 Excel 文件保存到本地。 ```csharp using (FileStream fileStream = new FileStream(filePath, FileMode.Create)) { workbook.Write(fileStream); } ``` 完整的代码示例如下: ```csharp using System.IO; using NPOI.HSSF.UserModel; //定义数据源 public class Person { public string Name { get; set; } public int Age { get; set; } public string Gender { get; set; } } public static void ExportToExcel(Person[] dataSource, string filePath) { //创建一个 Excel 文件并设置其属性 HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.CreateSheet("Sheet1"); //创建表头信息 HSSFRow headerRow = sheet.CreateRow(0); headerRow.CreateCell(0).SetCellValue("姓名"); headerRow.CreateCell(1).SetCellValue("年龄"); headerRow.CreateCell(2).SetCellValue("性别"); //遍历数据源,将数据写入到 Excel 文件 for (int i = 0; i < dataSource.Length; i++) { HSSFRow dataRow = sheet.CreateRow(i + 1); dataRow.CreateCell(0).SetCellValue(dataSource[i].Name); dataRow.CreateCell(1).SetCellValue(dataSource[i].Age); dataRow.CreateCell(2).SetCellValue(dataSource[i].Gender); } //将 Excel 文件保存到本地 using (FileStream fileStream = new FileStream(filePath, FileMode.Create)) { workbook.Write(fileStream); } } ``` 你可以将数据源以及文件路径传入到 ExportToExcel 方法,就可以实现快速导出 Excel 表格了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值