Winform导出DataGridView当前页以及全部数据

前言:基本上,所有的业务系统都会要求有导出的功能,很多人会选择在每个列表页加入导出按钮进行导出;其实,个人感觉挺麻烦的。不知道有多少用过Dev控件的,Dev的GridView控件自带导出功能有没有觉得很好用?这一篇就动手实现原生DataGridView的导出功能。.

  1. 新建一个自定义控件继承自DataGridView,并在其中定义以下属性

[Description("可导出的最大数量")]public int ExportMaxCount { get; set; } = 5000;
  1. 由于是要让DataGridView自带导出控件,所以这里使用右键菜单来做,并在OnCreateControl事件中进行导出的具体实现。

    ContextMenuStrip contextMenuStrip = new ContextMenuStrip();protected override void OnCreateControl(){    base.OnCreateControl();    contextMenuStrip.Items.Add(new ToolStripMenuItem("导出当前页", null, (s, e) =>            {                if (Rows.Count == 0)                {                    FrmDialog.ShowMessage("没有数据", "提示");                    return;                }                SaveFileDialog saveFileDialog = new SaveFileDialog();                saveFileDialog.Filter = "Excel文件|*.xlsx";                if (saveFileDialog.ShowDialog() == DialogResult.OK)                {                    DataTable dt = new DataTable();                    foreach (DataGridViewColumn column in Columns)                    {                        dt.Columns.Add(new DataColumn                        {                            ColumnName = column.DataPropertyName,                            Caption = column.HeaderText                        });                    }                    foreach (DataGridViewRow dr in Rows)                    {                        DataRow dataRow = dt.NewRow();                        for (int i = 0; i < dt.Columns.Count; i++)                        {                            dataRow[i] = dr.Cells[i].Value;                        }                        dt.Rows.Add(dataRow);                    }                    ExcelUtils.Export(dt, saveFileDialog.FileName);                    if (MessageBox.Show("导出成功,是否打开?", "提示", MessageBoxButtons.YesNo) == DialogResult.Yes)                    {                        Process.Start(saveFileDialog.FileName);                    }                }            }));            this.ContextMenuStrip = contextMenuStrip;
  1. 导出是使用NPOI来实现的,具体代码如下,也可参考之前的导出文章

    public static void Export(DataTable dataSource, string fileName)        {            IWorkbook workbook = new XSSFWorkbook();            ISheet sheet = workbook.CreateSheet("sheet1");            IRow rowHead = sheet.CreateRow(0);            for (int j = 0; j < dataSource.Columns.Count; j++)            {                rowHead.CreateCell(j).SetCellValue(dataSource.Columns[j].Caption);            }            for (int i = 0; i < dataSource.Rows.Count; i++)            {                IRow row = sheet.CreateRow(i + 1);                for (int j = 0; j < dataSource.Columns.Count; j++)                {                    row.CreateCell(j).SetCellValue(Convert.ToString(dataSource.Rows[i][j]));                }            }            using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))            {                workbook.Write(fs);            }            workbook.Close();        }
  1. 到这里,其实就实现了一个公用的带导出功能的DataGridView控件,但是我们一般都会对数据进行分页显示,也会有导出全部的功能,这就要重新去获取服务端的全部数据(这里也可以由后端直接生成提供下载地址)。所以我们在控件中需要增加一个导出全部的事件,如果对事件进行了注册的话,可以在OnMouseDown事件中重新添加一个导出全部的右键菜单,并且可以触发该事件。

    public EventHandler ExportAllData;protected override void OnMouseDown(MouseEventArgs e)        {            base.OnMouseDown(e);            if (e.Button == MouseButtons.Right && ExportAllData != null && !contextMenuStrip.Items.ContainsKey("导出全部"))            {                contextMenuStrip.Items.Add(new ToolStripMenuItem("导出全部", null, ExportAllData, "导出全部"));                this.ContextMenuStrip = contextMenuStrip;            }        }
  1. 最后调用的时候就在ExportAllData事件中进行导出即可。

实现效果:

Winform导出DataGridView当前页以及全部数据