datatable或者datagridview中的数据导出到excel中

在做winform窗体编程的时候,很多时候都需要把datatable中的数据或者datagridview中的数据导出到excel中,供用户查看。而且在导出时又分为单文件单表格和单文件多表格导出。

单文件单表格:一个excel文件,里面只有一个sheet

单文件多表格:一个excel文件,里面有多个sheet

话不多说,直接上代码:

导出辅助类: 

using NPOI.HSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public class ExcelHelp
    {

        [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>
        /// NPOI DataGridView 导出 EXCEL
        /// </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)
        {
            //检测是否有数据
            //定义表格内数据的行数和列数    
            int rowscount = dgv.Rows.Count;
            int colscount = dgv.Columns.Count;
            //行数必须大于0    
            if (rowscount <= 0)
            {
                MessageBox.Show("没有数据可供保存 ", "提示 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            //列数必须大于0    
            if (colscount <= 0)
            {
                MessageBox.Show("没有数据可供保存 ", "提示 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            //if (dgv.SelectedRows.Count == 0) return;
            //创建主要对象
            HSSFWorkbook workbook = new HSSFWorkbook();
            HSSFSheet sheet = (HSSFSheet)workbook.CreateSheet("Weight");
            //设置字体,大小,对齐方式
            HSSFCellStyle style = (HSSFCellStyle)workbook.CreateCellStyle();
            HSSFFont font = (HSSFFont)workbook.CreateFont();
            font.FontName = fontname;
            font.FontHeightInPoints = fontsize;
            style.SetFont(font);
            style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.CENTER; //居中对齐
            //添加表头
            HSSFRow dataRow = (HSSFRow)sheet.CreateRow(0);
            for (int i = 0; i < dgv.Columns.Count; i++)
            {
                dataRow.CreateCell(i).SetCellValue(dgv.Columns[i].HeaderText);
                dataRow.GetCell(i).CellStyle = style;
            }
            //注释的这行是设置筛选的
            //sheet.SetAutoFilter(new CellRangeAddress(0, dgv.Columns.Count, 0, dgv.Columns.Count));
            //添加列及内容
            for (int i = 0; i < dgv.Rows.Count ; i++)
            {
                dataRow = (HSSFRow)sheet.CreateRow(i + 1);
                for (int j = 0; j < dgv.Columns.Count; j++)
                {
                    string ValueType = dgv.Rows[i].Cells[j].Value.GetType().ToString();                    
                    string Value = dgv.Rows[i].Cells[j].Value.ToString().Trim();                    
                    switch (ValueType)
                    {
                        case "System.String"://字符串类型
                            dataRow.CreateCell(j).SetCellValue(Value);
                            break;
                        case "System.DateTime"://日期类型
                            System.DateTime dateV;
                            System.DateTime.TryParse(Value, out dateV);
                            dataRow.CreateCell(j).SetCellValue(dateV);
                            break;
                        case "System.Boolean"://布尔型
                            bool boolV = false;
                            bool.TryParse(Value, out boolV);
                            dataRow.CreateCell(j).SetCellValue(boolV);
                            break;
                        case "System.Int16"://整型
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Byte":
                            int intV = 0;
                            int.TryParse(Value, out intV);
                            dataRow.CreateCell(j).SetCellValue(intV);
                            break;
                        case "System.Decimal"://浮点型
                        case "System.Double":
                            double doubV = 0;
                            double.TryParse(Value, out doubV);
                            dataRow.CreateCell(j).SetCellValue(doubV);
                            break;
                        case "System.DBNull"://空值处理
                            dataRow.CreateCell(j).SetCellValue("");
                            break;
                        case "System.Byte[]"://二进制文件
                            string str = System.Text.Encoding.GetEncoding("iso-8859-1").GetString((byte[])dgv.Rows[i].Cells[j].Value);
                      //      byte[] data = System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(str);
                            if (str.Length < 31000)
                            {
                                dataRow.CreateCell(j).SetCellValue(str);
                            }
                            else
                            {
                                string strSub = "";
                                for (int n = 0; n <= str.Length / 30000; n++)
                                {                                 
                                    if (str.Length - n * 30000 - 1 >= 30000)
                                        strSub = str.Substring(n * 30000, 30000);
                                    if (str.Length - n * 30000 - 1 < 30000)
                                        strSub = str.Substring(n * 30000, str.Length - n * 30000);
                                    dataRow.CreateCell(j + n).SetCellValue(strSub);
                                }            
                            }                                              
                            break;
                        default:
                            dataRow.CreateCell(j).SetCellValue("");
                            break;
                    }
                    dataRow.GetCell(j).CellStyle = style;
                    // 设置宽度
                    sheet.SetColumnWidth(j, (Value.Length + 10) * 256);
                }
            }
            //保存文件
            string saveFileName = "";
            SaveFileDialog saveDialog = new SaveFileDialog();
            saveDialog.DefaultExt = "xls";
            saveDialog.Filter = "Excel文件|*.xls";
            saveDialog.FileName = fileName;
            MemoryStream ms = new MemoryStream();
            if (saveDialog.ShowDialog() == DialogResult.OK)
            {
                saveFileName = saveDialog.FileName;
                if (!CheckFiles(saveFileName))
                {
                    MessageBox.Show("文件被占用,请关闭文件 " + saveFileName);
                    workbook = null;
                    ms.Close();
                    ms.Dispose();
                    return;
                }
                workbook.Write(ms);
                FileStream file = new FileStream(saveFileName, FileMode.Create);
                workbook.Write(file);
                file.Close();
                workbook = null;
                ms.Close();
                ms.Dispose();
                MessageBox.Show("文件保存成功", "提示", MessageBoxButtons.OK);
            }
            else
            {
                workbook = null;
                ms.Close();
                ms.Dispose();
            }
        }
        
        



        /// <summary>
        /// 检测文件被占用 
        /// </summary>
        /// <param name="FileNames">要检测的文件路径</param>
        /// <returns></returns>
        public bool CheckFiles(string FileNames)
        {
            IntPtr vHandle = _lopen(FileNames, OF_READWRITE | OF_SHARE_DENY_NONE);
            if (vHandle == HFILE_ERROR)
            {
                //文件被占用
                return false;
            }
            //文件没被占用
            CloseHandle(vHandle);
            return true;
        }


        


        public void ExportExcel2( MemoryStream ms ,Dictionary<string,DataTable> dic, string fontname, short fontsize,string saveFileName)
        {
            
            //if (dt.SelectedRows.Count == 0) return;
            //创建主要对象
            HSSFWorkbook workbook = new HSSFWorkbook();

            DataTable dt;
            foreach (string item in dic.Keys)
            {
                string sf = item.Trim();
                dic.TryGetValue(sf,out dt);

                HSSFSheet sheet = (HSSFSheet)workbook.CreateSheet(sf);
                //设置字体,大小,对齐方式
                HSSFCellStyle style = (HSSFCellStyle)workbook.CreateCellStyle();
                HSSFFont font = (HSSFFont)workbook.CreateFont();
                font.FontName = fontname;
                font.FontHeightInPoints = fontsize;
                style.SetFont(font);
                style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.CENTER; //居中对齐
                                                                                //添加表头
                HSSFRow dataRow = (HSSFRow)sheet.CreateRow(0);
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    dataRow.CreateCell(i).SetCellValue(dt.Columns[i].ColumnName);
                    dataRow.GetCell(i).CellStyle = style;
                }
                //注释的这行是设置筛选的
                //sheet.SetAutoFilter(new CellRangeAddress(0, dt.Columns.Count, 0, dt.Columns.Count));
                //添加列及内容
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    dataRow = (HSSFRow)sheet.CreateRow(i + 1);
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        string ValueType = "System.String";
                        string Value = dt.Rows[i][j].ToString().Trim();
                        switch (ValueType)
                        {
                            case "System.String"://字符串类型
                                dataRow.CreateCell(j).SetCellValue(Value);
                                break;
                            case "System.DateTime"://日期类型
                                System.DateTime dateV;
                                System.DateTime.TryParse(Value, out dateV);
                                dataRow.CreateCell(j).SetCellValue(dateV);
                                break;
                            case "System.Boolean"://布尔型
                                bool boolV = false;
                                bool.TryParse(Value, out boolV);
                                dataRow.CreateCell(j).SetCellValue(boolV);
                                break;
                            case "System.Int16"://整型
                            case "System.Int32":
                            case "System.Int64":
                            case "System.Byte":
                                int intV = 0;
                                int.TryParse(Value, out intV);
                                dataRow.CreateCell(j).SetCellValue(intV);
                                break;
                            case "System.Decimal"://浮点型
                            case "System.Double":
                                double doubV = 0;
                                double.TryParse(Value, out doubV);
                                dataRow.CreateCell(j).SetCellValue(doubV);
                                break;
                            case "System.DBNull"://空值处理
                                dataRow.CreateCell(j).SetCellValue("");
                                break;
                            case "System.Byte[]"://二进制文件
                                string str = System.Text.Encoding.GetEncoding("iso-8859-1").GetString((byte[])dt.Rows[i][j]);
                                //      byte[] data = System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(str);
                                if (str.Length < 31000)
                                {
                                    dataRow.CreateCell(j).SetCellValue(str);
                                }
                                else
                                {
                                    string strSub = "";
                                    for (int n = 0; n <= str.Length / 30000; n++)
                                    {
                                        if (str.Length - n * 30000 - 1 >= 30000)
                                            strSub = str.Substring(n * 30000, 30000);
                                        if (str.Length - n * 30000 - 1 < 30000)
                                            strSub = str.Substring(n * 30000, str.Length - n * 30000);
                                        dataRow.CreateCell(j + n).SetCellValue(strSub);
                                    }
                                }
                                break;
                            default:
                                dataRow.CreateCell(j).SetCellValue("");
                                break;
                        }
                        dataRow.GetCell(j).CellStyle = style;
                        // 设置宽度
                        sheet.SetColumnWidth(j, (Value.Length + 10) * 256);
                    }
                }
            }

            workbook.Write(ms);
            FileStream file = new FileStream(saveFileName, FileMode.Create);
            workbook.Write(file);
            file.Close();
            
        }


    }
}

 

我们可以借助这个类,然后实现单文件单表格导出: 

这个方法里面是直接使用datagridview作为导出的数据源,然后直接调用help.ExportExcel(fileName, this.dataGridView1, "宋体", 11);进行导出,导出结果就是一个excel文件里面只含有一个名为weight的sheet。数据为datagridview中的数据。当然,这里也可以把datagridview换成datatable,然后把ExportExcel方法稍微调整即可。

private void sfbtn_Click(object sender, EventArgs e)
        {
            try
            {
                ExcelHelp help = new ExcelHelp();
                string fileName = "";
                if (cbsf.SelectedIndex == -1)
                {
                    MessageBox.Show("请选择院系");
                }
                else
                {
                    string sf = this.cbsf.SelectedItem.ToString();
                    fileName = sf + "学生成绩信息";
                    help.ExportExcel(fileName, this.dataGridView1, "宋体", 11);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }

        }

当然了,也可以实现单文件多表格导出:

为了实现一次性导出多个sheet,我将SaveFileDialog代码提取到ExportExcel2外面,然后调用ExportExcel2方法在一个文件中创建多个sheet,完成导出。我这里是将多个datatable放在dic中,因为我还要传递sheet名,如果不需要特定的名字,那么使用dataset来存储多个datatable也是不错的选择。同样的,这里也可以把ExportExcel2的参数改成dic里面放置datagridview,也只需要稍作调整即可。

private void allbtn_Click(object sender, EventArgs e)
        {
            try
            {
                ExcelHelp help = new ExcelHelp();
                string fileName = "所有省份成绩信息表";

                SaveFileDialog saveDialog = new SaveFileDialog();
                saveDialog.DefaultExt = "xls";
                saveDialog.Filter = "Excel文件|*.xls";
                saveDialog.FileName = fileName;
                MemoryStream ms = new MemoryStream();
                if (saveDialog.ShowDialog() == DialogResult.OK)
                {
                    string saveFileName = saveDialog.FileName;
                    if (!help.CheckFiles(saveFileName))
                    {
                        MessageBox.Show("文件被占用,请关闭文件 " + saveFileName);

                        ms.Close();
                        ms.Dispose();
                        return;
                    }
                    Dictionary<string, DataTable> dic = new Dictionary<string, DataTable>();
                    for (int i = 0; i < sfList.Count; i++)
                    {
                        string sf = sfList[i];
                        DataTable dt = getDtBySf(sf);
                        if (dt.Rows.Count > 0)
                        {
                            dic.Add(sf,dt);
                        }
                        
                    }
                    if (dic.Keys.Count>0)
                    {
                        help.ExportExcel2(ms, dic, "宋体", 11, saveFileName);
                        ms.Close();
                        ms.Dispose();
                        MessageBox.Show("文件保存成功", "提示", MessageBoxButtons.OK);
                    }
                    else
                    {
                        MessageBox.Show("没有数据可供保存!");
                        ms.Close();
                        ms.Dispose();
                        return;
                    }
                    
                }
                else
                {
                    ms.Close();
                    ms.Dispose();
                }


            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());

            }

over!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值