前言

https://blog.csdn.net/IT_xiao_guang_guang/article/details/104217491

 本地数据库表中有46785条数据,测试正常

 初次运行程序第一次导出,用时在4-5s左右;此后再导出用时在2-3s左右;可能与缓存有关


支持导出为.xls和.xlsx格式

可以自定义字体和字号

exe测试文件下载地址:https://www.lanzous.com/i95st5g

密码:test

实现步骤

一、安装NPOI

右键项目 → "管理NuGet程序包" → 搜索NPOI → 安装




二、创建类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;//导出xls格式用HSSF
using NPOI.XSSF.UserModel;//导出xlsx格式用XSSF
using System.IO;
using System.Runtime.InteropServices;
using System.Diagnostics;
using NPOI.SS.Util; namespace ExportToExcel
{
public class ExportDgvToExcel
{
#region NPOI DataGridView 导出 EXCEL
/// <summary>
/// NPOI DataGridView 导出 EXCEL
/// 03版Excel-xls最大行数是65536行,最大列数是256列
/// 07版Excel-xlsx最大行数是1048576行,最大列数是16384列
/// </summary>
/// <param name="fileName">默认保存文件名</param>
/// <param name="dgv">DataGridView</param>
/// <param name="fontname">字体名称</param>
/// <param name="fontsize">字体大小</param> public void ExportExcel(string fileName, DataGridView dgv, string fontname, short fontsize)
{
IWorkbook workbook;
ISheet sheet;
Stopwatch sw = null; //判断datagridview中内容是否为空
if (dgv.Rows.Count == 0)
{
MessageBox.Show("DataGridView中内容为空,请先导入数据!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
} //保存文件
string saveFileName = "";
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.DefaultExt = "xls";
saveFileDialog.Filter = "Excel文件(*.xls)|*.xls|Excel文件(*.xlsx)|*.xlsx";
saveFileDialog.RestoreDirectory = true;
saveFileDialog.Title = "Excel文件保存路径";
saveFileDialog.FileName = fileName;
MemoryStream ms = new MemoryStream(); //MemoryStream
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
//**程序开始计时**//
sw = new Stopwatch();
sw.Start(); saveFileName = saveFileDialog.FileName; //检测文件是否被占用
if (!CheckFiles(saveFileName))
{
MessageBox.Show("文件被占用,请关闭文件" + saveFileName);
workbook = null;
ms.Close();
ms.Dispose();
return;
}
}
else
{
workbook = null;
ms.Close();
ms.Dispose();
} //*** 根据扩展名xls和xlsx来创建对象
string fileExt = Path.GetExtension(saveFileName).ToLower();
if (fileExt == ".xlsx")
{
workbook = new XSSFWorkbook();
}
else if (fileExt == ".xls")
{
workbook = new HSSFWorkbook();
}
else
{
workbook = null;
}
//*** //创建Sheet
if (workbook != null)
{
sheet = workbook.CreateSheet("Sheet1");//Sheet的名称
}
else
{
return;
} //设置单元格样式
ICellStyle cellStyle = workbook.CreateCellStyle();
//水平居中对齐和垂直居中对齐
cellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
cellStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
//设置字体
IFont font = workbook.CreateFont();
font.FontName = fontname;//字体名称
font.FontHeightInPoints = fontsize;//字号
font.Color = NPOI.HSSF.Util.HSSFColor.Black.Index;//字体颜色
cellStyle.SetFont(font); //添加列名
IRow headRow = sheet.CreateRow(0);
for (int i = 0; i < dgv.Columns.Count; i++)
{
//隐藏行列不导出
if (dgv.Columns[i].Visible == true)
{
headRow.CreateCell(i).SetCellValue(dgv.Columns[i].HeaderText);
headRow.GetCell(i).CellStyle = cellStyle;
}
} //根据类型写入内容
for (int rowNum = 0; rowNum < dgv.Rows.Count; rowNum++)
{
///跳过第一行,第一行为列名
IRow dataRow = sheet.CreateRow(rowNum + 1);
for (int columnNum = 0; columnNum < dgv.Columns.Count; columnNum++)
{
int columnWidth = sheet.GetColumnWidth(columnNum) / 256; //列宽 //隐藏行列不导出
if (dgv.Rows[rowNum].Visible == true && dgv.Columns[columnNum].Visible == true)
{
//防止行列超出Excel限制
if (fileExt == ".xls")
{
//03版Excel最大行数是65536行,最大列数是256列
if (rowNum > 65536)
{
MessageBox.Show("行数超过Excel限制!");
return;
}
if (columnNum > 256)
{
MessageBox.Show("列数超过Excel限制!");
return;
}
}
else if (fileExt == ".xlsx")
{
//07版Excel最大行数是1048576行,最大列数是16384列
if (rowNum > 1048576)
{
MessageBox.Show("行数超过Excel限制!");
return;
}
if (columnNum > 16384)
{
MessageBox.Show("列数超过Excel限制!");
return;
}
} ICell cell = dataRow.CreateCell(columnNum);
if (dgv.Rows[rowNum].Cells[columnNum].Value == null)
{
cell.SetCellType(CellType.Blank);
}
else
{
if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Int32"))
{
cell.SetCellValue(Convert.ToInt32(dgv.Rows[rowNum].Cells[columnNum].Value));
}
else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.String"))
{
cell.SetCellValue(dgv.Rows[rowNum].Cells[columnNum].Value.ToString());
}
else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Single"))
{
cell.SetCellValue(Convert.ToSingle(dgv.Rows[rowNum].Cells[columnNum].Value));
}
else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Double"))
{
cell.SetCellValue(Convert.ToDouble(dgv.Rows[rowNum].Cells[columnNum].Value));
}
else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Decimal"))
{
cell.SetCellValue(Convert.ToDouble(dgv.Rows[rowNum].Cells[columnNum].Value));
}
else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.DateTime"))
{
cell.SetCellValue(Convert.ToDateTime(dgv.Rows[rowNum].Cells[columnNum].Value).ToString("yyyy-MM-dd"));
}
else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.DBNull"))
{
cell.SetCellValue("");
}
} //设置列宽
IRow currentRow;
if (sheet.GetRow(rowNum) == null)
{
currentRow = sheet.CreateRow(rowNum);
}
else
{
currentRow = sheet.GetRow(rowNum);
} if (currentRow.GetCell(columnNum) != null)
{
ICell currentCell = currentRow.GetCell(columnNum);
int length = Encoding.Default.GetBytes(currentCell.ToString()).Length; if (columnWidth < length)
{
columnWidth = length + 10; //设置列宽数值
}
}
sheet.SetColumnWidth(columnNum, columnWidth * 256); //单元格样式
dataRow.GetCell(columnNum).CellStyle = cellStyle;
}
}
} //保存为Excel文件
workbook.Write(ms);
FileStream file = new FileStream(saveFileName, FileMode.Create);
workbook.Write(file);
file.Close();
workbook = null;
ms.Close();
ms.Dispose(); //**程序结束计时**//
sw.Stop();
double totalTime = sw.ElapsedMilliseconds / 1000.0; MessageBox.Show(fileName + " 导出成功\n耗时" + totalTime + "s", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
#endregion #region 检测文件是否被占用
/// <summary>
/// 判定文件是否打开
/// </summary>
[DllImport("kernel32.dll")]
public static extern IntPtr _lopen(string lpPathName, int iReadWrite);
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr hObject);
public const int OF_READWRITE = 2;
public const int OF_SHARE_DENY_NONE = 0x40;
public readonly IntPtr HFILE_ERROR = new IntPtr(-1); /// <summary>
/// 检测文件被占用
/// </summary>
/// <param name="FileNames">要检测的文件路径</param>
/// <returns></returns>
public bool CheckFiles(string FileNames)
{
if (!File.Exists(FileNames))
{
//文件不存在
return true;
}
IntPtr vHandle = _lopen(FileNames, OF_READWRITE | OF_SHARE_DENY_NONE);
if (vHandle == HFILE_ERROR)
{
//文件被占用
return false;
}
//文件没被占用
CloseHandle(vHandle);
return true;
}
#endregion
}
}

三、调用

private void btnExport_Click_1(object sender, EventArgs e)
{
ExportDgvToExcel export = new ExportDgvToExcel();
export.ExportExcel("", dgv, "宋体", 11);//默认文件名,DataGridView控件的名称,字体,字号
}

C# 将DataGridView中显示的数据导出到Excel(.xls和.xlsx格式)—NPOI的更多相关文章

  1. C#将dataGridView中显示的数据导出到Excel(大数据量超有用版)

    开发中非常多情况下须要将dataGridView控件中显示的数据结果以Excel或者Word的形式导出来,本例就来实现这个功能. 因为从数据库中查找出某些数据列可能不是必需显示出来,在dataGrid ...

  2. MySQL数据导出为Excel, json,sql等格式

    MySQL数据经常要导出为Excel, json,sql等格式,通过步骤都很多,麻烦,现在通过Treesoft可以方便的导出你要的数据格式. 1.在线执行SQL,在数据列表中有相应按钮,方便的将数据导 ...

  3. 将C#datagridview控件的数据导出到Excel中

    1.添加引用Microsoft.Office.Interop.Excel. 2.程序代码引用using Excel = Microsoft.Office.Interop.Excel; 3.控件事件代码 ...

  4. 实现excel导入导出功能,excel导入数据到页面中,页面数据导出生成excel文件

    今天接到项目中的一个功能,要实现excel的导入,导出功能.这个看起来思路比较清楚,但是做起了就遇到了不少问题. 不过核心的问题,大家也不会遇到了.每个项目前台页面,以及数据填充方式都不一样,不过大多 ...

  5. 大批量数据导出到Excel的实现

    在平时的项目中,将数据导出到Excel的需求是很常见的,在此对一些常见的方法做以总结,并提供一种大数据量导出的实现. OLEDB   使用OLEDB可以很方便导出Excel,思路很简单,处理时将Exc ...

  6. 将Datagridview中的数据导出至Excel中

        首先添加一个模块ImportToExcel,并添加引用         然后导入命名空间: Imports Microsoft.Office.Interop Imports System.Da ...

  7. Asp.net网页中DataGridView数据导出到Excel

    经过上网找资料,终于找到一种可以直接将GridView中数据导出到Excel文件的方法,归纳方法如下: 1. 注:其中的字符集格式若改为“GB2312”,导出的部分数据可能为乱码: 导出之前需要关闭分 ...

  8. 学习笔记 DataGridView数据导出为Excel

    DataGridView数据导出为Excel   怎样把WinForm下的“DGV”里的绑定数据库后的数据导出到Excel中. 比如:在窗体里有个一“DGV”,DataGridView1,绑定了数据源 ...

  9. vb.net-三种将datagridview数据导出为excel文件的函数

    第一种方法较慢,但是数据格式都比较好,需要引用excel的 Microsoft.Office.Interop.Excel.dll  office.dll #Region "导出excel函数 ...

随机推荐

  1. Vuejs开发环境的搭建

    Windows系统上搭建VueJS开发环境 1.安装node.js:在node.js官网下载对应系统的msi包并安装 注:node的安装分全局和本地模式.一般情况下会以本地模式运行,包会被安装到和你的 ...

  2. Codeforce 588A - Duff and Meat (贪心)

    Duff is addicted to meat! Malek wants to keep her happy for n days. In order to be happy in i-th day ...

  3. [Agc001A/At1979] BBQ Easy - 贪心

    要准备N组食物, 他有2N的食材, 需要两两组成一个食物, 食物的价值是两食材中较小的那个. 问最大总价值是多少 ---------- 考虑到\(ans = (sum - delta)/2\),只需要 ...

  4. JFinal获取多个model

    个人博客 地址:http://www.wenhaofan.com/article/20180930112646 由于jfinal框架自身没有实现获取多个同一类型的Model的方法,导致获取ModelL ...

  5. Python-selenium,使用SenKey模块时所碰到的坑

    一.SenKey模块(模拟鼠标键盘操作) :python3中没有该模块,使用PyUserInput模块代替 二.PyUserInput模块安装前需要安装:pywin32和pyHook模块,pywin3 ...

  6. django orm查询和后端缓存的使用

    django orm 查询 1 字段后(db_column='age') (null=True)#表示数据库里面的该字段数据可以为空 (blank=True)#表示前端表单提交的时候可以为空 (db_ ...

  7. Controller 和 Action -1

    https://www.cnblogs.com/willick/p/3331521.html MVC 的每个请求都会提交到 Controller 处理.Controller 包含了对请求的逻辑处理,能 ...

  8. yolov3 讲解

    参考博客:https://blog.csdn.net/litt1e/article/details/88907542

  9. 题解【洛谷P3958】[NOIP2017]奶酪

    题面 题解 我们考虑使用一个并查集维护空洞之间的关系. 如果两个空洞能相互到达,那么它们的祖先也是相同的. 枚举从哪一个空洞开始,能否到达奶酪的上表面. 如果能到达就输出Yes,否则输出No. 注意开 ...

  10. 《TCP/IP入门经典》摘录--Part 1

    TCP/IP基础知识 什么是TCP/IP Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议, ...