将mySql数据库导出excel,以sheet形式导出表,和目录

9 篇文章 0 订阅

将mySql数据库导出excel,以sheet形式导出表,+目录

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Excel = Microsoft.Office.Interop.Excel;

namespace Export_ExcelSheet
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            //指定数据库所有表
            string str_sql = "select table_name 表名,table_comment 注释 from information_schema.tables where table_schema = 'imos_7'";
            string msg = "";
            DataSet ds_allDatable = IMOS.DBUtility.DBHelperMySQL.GetDataSet(str_sql, out msg);
            string strFileName = System.IO.Directory.GetCurrentDirectory() + @"\" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls";

            ToExcelSheet_MoreSheet(ds_allDatable.Tables[0], strFileName);
        }
        #region 导出到excel多sheet的两种方法
        /// <summary>
        /// 生成sheet
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="strFileName"></param>
        private void ToExcelSheet_MoreSheet(DataTable dt, string strFileName)
        {
            //Exsel模板 
            string templetFile = System.IO.Directory.GetCurrentDirectory() + @"\Temp\template.xls";
            System.Reflection.Missing miss = System.Reflection.Missing.Value;
            //创建EXCEL对象appExcel,Workbook对象,Worksheet对象,Range对象
            Excel.Application appExcel;
            appExcel = new Excel.Application();

            Excel.Workbook workbookData;
            Excel.Worksheet worksheetData;
          
            Excel.Range rangedata;
            //设置对象不可见
            appExcel.Visible = false;
            /* 在调用Excel应用程序,或创建Excel工作簿之前,记着加上下面的两行代码
             * 这是因为Excel有一个Bug,如果你的操作系统的环境不是英文的,而Excel就会在执行下面的代码时,报异常。
             */
            System.Globalization.CultureInfo CurrentCI = System.Threading.Thread.CurrentThread.CurrentCulture;
            System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
            //以新建的方式
            workbookData = appExcel.Workbooks.Add(miss);
            //以模板的方式
            //workbookData = appExcel.Workbooks.Open(templetFile, miss, miss, miss, miss, miss, miss, miss, miss, miss, miss, miss, miss); 
            try
            {
                for (int k = 0; k < dt.Rows.Count; k++)
                {
                    try
                    {
                        string table_name = dt.Rows[k]["表名"].ToString().Replace(" ", "");
                        string table_des = dt.Rows[k]["注释"].ToString().Replace(" ", "");
                        string sheetName = table_name;

                        //查询表结构
                        string str_sql = @"SELECT 
                                            column_name 字段,
                                            data_type 字段类型,
	                                        column_comment 注释, 
                                            '' AS '是否使用',
	                                        '' AS '来源表',
	                                        '' AS '来源表字段'
                                        FROM

                                            information_schema.COLUMNS
                                        WHERE

                                            table_schema = 'imos_7' AND table_name = '" + table_name + "'";

                        string msg = "";
                        //worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value);
                        worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add();
                        if (table_name.Length > 25)
                        {
                            sheetName = table_name.Substring(0, 24) + "_" + k;
                        }
                        //sheet名称
                        worksheetData.Name = sheetName;
                        //查询表结构
                        DataTable obj_dt = IMOS.DBUtility.DBHelperMySQL.GetDataSet(str_sql, out msg).Tables[0];
                        添加超链接返回目录
                        //Excel.Range rangeLink = worksheetData.get_Range("B1");
                        //rangeLink.Value = "<<返回目录";
                        //worksheetData.Hyperlinks.Add(rangeLink, "#Sheet1!A1", Type.Missing, Type.Missing, Type.Missing);

                        //表title
                        Excel.Range rangeTile = worksheetData.get_Range("B2", "G2");
                        rangeTile.Font.Italic = true;//斜体
                        rangeTile.Merge(0);
                        rangeTile.Value = "表:" + table_name + "  " + table_des;

                        //从第3行开始生成表头
                        int rowStart = 3;
                        #region 生成表头
                        //生成表头表字段(表头)
                        for (int i = 0; i < obj_dt.Columns.Count; i++)
                        {
                            worksheetData.Cells[rowStart, i + 2] = obj_dt.Columns[i].ColumnName.ToString();
                        }
                        //列行字体加粗
                        Excel.Range rangeFiled = worksheetData.get_Range("B3", "G3");
                        rangeFiled.Font.Bold = true;
                        #endregion

                        //先给Range对象一个范围为A2开始,Range对象可以给一个CELL的范围,也可以给例如A1到H10这样的范围
                        //因为第一行已经写了表头,所以所有数据都应该从A2开始
                        rangedata = worksheetData.get_Range("B4", miss);
                        Excel.Range xlRang = null;
                        //总行数
                        int iRowCount = obj_dt.Rows.Count;
                        //iEachSize当前每次导出的行数的页面大小,可以自己设置
                        int iEachSize = 100;
                        //已导出的行数     ,当前每次导出的行数大小
                        int iParstedRow = 0, iCurrSize = 0;

                        //列数
                        int iColumnAccount = obj_dt.Columns.Count;
                        //在内存中声明一个iEachSize×iColumnAccount的数组,iEachSize是每次最大存储的行数,iColumnAccount就是存储的实际列数
                        object[,] objVal = new object[iEachSize, iColumnAccount];

                        iCurrSize = iEachSize;
                        /*
                            //方法一:Cell方法导出表数据
                            for (int i = 0; i < obj_dt.Rows.Count; i++)
                            {
                                for (int j = 0; j < obj_dt.Columns.Count; j++)
                                {
                                    //worksheetData.Cells[i + 2, j + 1] = obj_dt.Rows[i][j].ToString();
                                    objVal[i, j] = obj_dt.Rows[i][j].ToString();
                                }
                                System.Windows.Forms.Application.DoEvents();
                            }
                             */
                        //方法二:Range方法导出表数据(此方法导出很快,建议用此方法)
                        while (iParstedRow < iRowCount)
                        {
                            //总行数-已导出行数;剩余行数是否小于页面大小,小于的话,当前导出行数为余行
                            if ((iRowCount - iParstedRow) < iEachSize)
                            {
                                iCurrSize = iRowCount - iParstedRow;
                            }
                            for (int i = 0; i < iCurrSize; i++)
                            {
                                for (int j = 0; j < iColumnAccount; j++)
                                {
                                    //objVal[i, j] = gridView[j, i + iParstedRow].Value.ToString();
                                    objVal[i, j] = obj_dt.Rows[i + iParstedRow][j].ToString();

                                }

                                //System.Windows.Forms.Application.DoEvents();
                            }

                            /*
                                     * 建议使用设置断点研究下哈
                                     * 例如A1到H10的意思是从A到H,第一行到第十行
                                     * 下句很关键,要保证获取workSheet中对应的Range范围
                                     * 下句实际上是得到这样的一个代码语句xlRang = worksheetData.get_Range("A2","H100");
                                     * 注意看实现的过程
                                     * 'A' + iColumnAccount - 1这儿是获取你的最后列,A的数字码为65,大家可以仔细看下是不是得到最后列的字母
                                     * iParstedRow + iCurrSize + 1获取最后行
                                     * 若WHILE第一次循环的话这应该是A2,最后列字母+最后行数字
                                     * iParstedRow + 2要注意,每次循环这个值不一样,他取决于你每次循环RANGE取了多大,也就是iEachSize设置值的大小哦
                                     */
                            xlRang = worksheetData.get_Range("B" + ((int)(iParstedRow + 1 + rowStart)).ToString(), ((char)('B' + iColumnAccount - 1)).ToString() + ((int)(iParstedRow + iCurrSize + rowStart)).ToString());
                            // 调用Range的Value2属性,把内存中的值赋给Excel
                            xlRang.Value2 = objVal;
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRang);
                            xlRang = null;
                            //已导出的行数=已导出的行数+当前导出行数
                            iParstedRow = iParstedRow + iCurrSize;
                        }

                        worksheetData.Columns.EntireColumn.AutoFit();
                        workbookData.Saved = true;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "警告");
                    }

                }
                //目录
                worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add();
                worksheetData.Name = "目录";

                //workbookData.SaveAs(strFileName);
                workbookData.SaveAs(strFileName + "", miss, miss, miss, miss, miss, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, miss, miss, miss);
                appExcel.Quit();
                // 别忘了在结束程序之前恢复你的环境!
                System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCI;
                GC.Collect();

                MessageBox.Show("导出完成!", "提示信息");
            }
            catch (Exception ex)
            {
                //appExcel.Quit();
                //调用方法关闭EXCEL进程,大家可以试下不用的话如果程序不关闭在进程里一直会有EXCEL.EXE这个进程并锁定你的EXCEL表格
                //this.KillSpecialExcel(appExcel);
                // 别忘了在结束程序之前恢复你的环境!
                System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCI;
                GC.Collect();
                MessageBox.Show(ex.Message, "警告");

            }

        }
        /// <summary>
        /// 生成目录
        /// </summary>
        /// <param name="ds"></param>
        /// <param name="strFileName"></param>
        private void ToExcelSheet(DataSet ds, string strFileName)
        {
            //Exsel模板 
            string templetFile = System.IO.Directory.GetCurrentDirectory() + @"\Temp\template.xls";
            System.Reflection.Missing miss = System.Reflection.Missing.Value;
            //创建EXCEL对象appExcel,Workbook对象,Worksheet对象,Range对象
            Excel.Application appExcel;
            appExcel = new Excel.Application();

            Excel.Workbook workbookData;
            Excel.Worksheet worksheetData;
            Excel.Range rangedata;
            //设置对象不可见
            appExcel.Visible = false;
            /* 在调用Excel应用程序,或创建Excel工作簿之前,记着加上下面的两行代码
             * 这是因为Excel有一个Bug,如果你的操作系统的环境不是英文的,而Excel就会在执行下面的代码时,报异常。
             */
            System.Globalization.CultureInfo CurrentCI = System.Threading.Thread.CurrentThread.CurrentCulture;
            System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
            //以新建的方式
            // workbookData = appExcel.Workbooks.Add(miss);
            //以模板的方式
            workbookData = appExcel.Workbooks.Open(templetFile, miss, miss, miss, miss, miss, miss, miss, miss, miss, miss, miss, miss);

            try
            {
                for (int k = 0; k < ds.Tables.Count; k++)
                {
                    worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value);
                    //worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add();
                    worksheetData.Name = ds.Tables[k].TableName;

                    if (ds.Tables[k] != null)
                    {
                        #region 生成表头
                        //生成表头表字段(表头)
                        for (int i = 0; i < ds.Tables[k].Columns.Count; i++)
                        {
                            worksheetData.Cells[i + 2] = ds.Tables[k].Columns[i].ColumnName.ToString();
                        }
                        #endregion

                        //先给Range对象一个范围为A2开始,Range对象可以给一个CELL的范围,也可以给例如A1到H10这样的范围
                        //因为第一行已经写了表头,所以所有数据都应该从A2开始
                        rangedata = worksheetData.get_Range("B1", miss);
                        Excel.Range xlRang = null;
                        //总行数
                        int iRowCount = ds.Tables[k].Rows.Count;
                        //iEachSize当前每次导出的行数的页面大小,可以自己设置
                        int iEachSize = 100;
                        //已导出的行数     ,当前每次导出的行数大小
                        int iParstedRow = 0, iCurrSize = 0;

                        //列数
                        int iColumnAccount = ds.Tables[k].Columns.Count;
                        //在内存中声明一个iEachSize×iColumnAccount的数组,iEachSize是每次最大存储的行数,iColumnAccount就是存储的实际列数
                        object[,] objVal = new object[iEachSize, iColumnAccount];

                        iCurrSize = iEachSize;
                        /*
                        //方法一:Cell方法导出表数据
                        for (int i = 0; i < ds.Tables[k].Rows.Count; i++)
                        {
                            for (int j = 0; j < ds.Tables[k].Columns.Count; j++)
                            {
                                //worksheetData.Cells[i + 2, j + 1] = ds.Tables[k].Rows[i][j].ToString();
                                objVal[i, j] = ds.Tables[k].Rows[i][j].ToString();
                            }
                            System.Windows.Forms.Application.DoEvents();
                        }
                         */
                        //方法二:Range方法导出表数据(此方法导出很快,建议用此方法)
                        while (iParstedRow < iRowCount)
                        {
                            //总行数-已导出行数;剩余行数是否小于页面大小,小于的话,当前导出行数为余行
                            if ((iRowCount - iParstedRow) < iEachSize)
                            {
                                iCurrSize = iRowCount - iParstedRow;
                            }
                            for (int i = 0; i < iCurrSize; i++)
                            {
                                for (int j = 0; j < iColumnAccount; j++)
                                {
                                    //objVal[i, j] = gridView[j, i + iParstedRow].Value.ToString();
                                    objVal[i, j] = ds.Tables[k].Rows[i + iParstedRow][j].ToString();

                                }

                                //System.Windows.Forms.Application.DoEvents();
                            }

                            /*
                                 * 建议使用设置断点研究下哈
                                 * 例如A1到H10的意思是从A到H,第一行到第十行
                                 * 下句很关键,要保证获取workSheet中对应的Range范围
                                 * 下句实际上是得到这样的一个代码语句xlRang = worksheetData.get_Range("A2","H100");
                                 * 注意看实现的过程
                                 * 'A' + iColumnAccount - 1这儿是获取你的最后列,A的数字码为65,大家可以仔细看下是不是得到最后列的字母
                                 * iParstedRow + iCurrSize + 1获取最后行
                                 * 若WHILE第一次循环的话这应该是A2,最后列字母+最后行数字
                                 * iParstedRow + 2要注意,每次循环这个值不一样,他取决于你每次循环RANGE取了多大,也就是iEachSize设置值的大小哦
                                 */
                            xlRang = worksheetData.get_Range("B" + ((int)(iParstedRow + 2)).ToString(), ((char)('B' + iColumnAccount - 1)).ToString() + ((int)(iParstedRow + iCurrSize + 1)).ToString());
                            // 调用Range的Value2属性,把内存中的值赋给Excel
                            xlRang.Value2 = objVal;
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRang);
                            xlRang = null;
                            //已导出的行数=已导出的行数+当前导出行数
                            iParstedRow = iParstedRow + iCurrSize;
                        }
                    }

                    worksheetData.Columns.EntireColumn.AutoFit();
                    workbookData.Saved = true;

                }


                //workbookData.SaveAs(strFileName);
                workbookData.SaveAs(strFileName + "", miss, miss, miss, miss, miss, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, miss, miss, miss);
                appExcel.Quit();
                // 别忘了在结束程序之前恢复你的环境!
                System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCI;
                GC.Collect();

                MessageBox.Show("导出完成!", "提示信息");
            }
            catch (Exception ex)
            {
                appExcel.Quit();
                //调用方法关闭EXCEL进程,大家可以试下不用的话如果程序不关闭在进程里一直会有EXCEL.EXE这个进程并锁定你的EXCEL表格
                //this.KillSpecialExcel(appExcel);
                // 别忘了在结束程序之前恢复你的环境!
                System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCI;
                GC.Collect();
                MessageBox.Show(ex.Message, "警告");

            }

        }
        #endregion 
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bingo_BIG

你的鼓励是我最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值