关于OFFICE(Excel和Word等)导出功能

1 篇文章 0 订阅

1、写在前面

首先,office组件是基于X86系统的,故一般项目平台选择"X86"编译

office 2007以下:Provider=Microsoft.Jet.OLEDB.4.0;Data Source=1.xls;Extended Properties="Excel 8.0;HDR=YES;IMEX=1"

office 2007及以上:Provider=Microsoft.ACE.OLEDB.12.0;Data Source=1.xls;Extended Properties="Excel 12.0;HDR=YES;IMEX=1"

2、导出代码1

bool DataTable2Excel(DataTable dataTable, string fileName, int rowsCount)
        {
            bool rt = false;//用于返回值
            if (dataTable == null && rowsCount < 1)
            {
                return false;
            }
            string sheetname = "sheet";
            int rowNum = dataTable.Rows.Count;//获取行数
            int colNum = dataTable.Columns.Count;//获取列数
            int SheetNum = (rowNum - 1) / rowsCount + 1; //获取工作表数
            string sqlText = "";//带类型的列名
            string sqlValues = "";//值
            string colCaption = "";//列名
            for (int i = 0; i < colNum; i++)
            {
                if (i != 0)
                {
                    sqlText += " , ";
                    colCaption += " , ";
                }

                sqlText += "[" + dataTable.Columns[i].Caption.ToString() + "] TEXT";
                colCaption += "[" + dataTable.Columns[i].Caption.ToString() + "]";
            }

            String sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + fileName + ";Extended Properties='Excel 12.0;HDR=NO;IMEX=1'";
            sConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + fileName + "; Extended Properties=Excel 12.0;";
            OleDbConnection cn = new OleDbConnection(sConnectionString);
            try
            {
                int sheet = 1;//表数
                int dbRow = 0;//数据的行数
                //打开连接
                cn.Open();
                while (sheet <= SheetNum)
                {
                    string sqlCreate = "CREATE TABLE [" + sheetname + sheet.ToString() + "] (" + sqlText + ")";
                    OleDbCommand cmd = new OleDbCommand(sqlCreate, cn);
                    //创建Excel文件
                    cmd.ExecuteNonQuery();
                    
                    for (int srow = 0; srow < rowsCount; srow++)
                    {
                        sqlValues = "";
                        for (int col = 0; col < colNum; col++)
                        {
                            if (col != 0)
                            {
                                sqlValues += " , ";
                            }
                            sqlValues += "'" + dataTable.Rows[dbRow][col].ToString() + "'";//拼接Value语句
                        }
                        String queryString = "INSERT INTO [" + sheetname + sheet.ToString() + "] (" + colCaption + ") VALUES (" + sqlValues + ")";
                        cmd.CommandText = queryString;
                        cmd.ExecuteNonQuery();//插入数据
                        dbRow++;//目前数据的行数自增
                        if (dbRow >= rowNum)
                        {
                            //目前数据的行数等于rowNum时退出循环
                            break;
                        }
                    }
                    sheet++;
                }
                rt = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                cn.Close();
            }
            return rt;
        }

3、导出代码2

public void ToExcel2(DataTable dt, string strName)
        {
            //System.Reflection.Missing miss = System.Reflection.Missing.Value;
            创建EXCEL对象appExcel,Workbook对象,Worksheet对象,Range对象
            //Microsoft.Office.Interop.Excel.Application appExcel;
            //appExcel = new Microsoft.Office.Interop.Excel.Application();
            //Microsoft.Office.Interop.Excel.Workbook workbookData;
            //Microsoft.Office.Interop.Excel.Worksheet worksheetData;
            //Microsoft.Office.Interop.Excel.Range rangedata;
            //设置对象不可见
            m_excel.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");
            //m_workbook = m_excel.Workbooks.Add(miss);
            //m_worksheet = (Microsoft.Office.Interop.Excel.Worksheet)m_workbook.Worksheets.Add(miss, miss, miss, miss);
            //给工作表赋名称
            //m_worksheet.Name = "saved";

            // 保存到WorkSheet的表头,你应该看到,是一个Cell一个Cell的存储,这样效率特别低,解决的办法是,使用Rang,一块一块地存储到Excel
            //for (int i = 0; i < dt.Columns.Count; i++)
            //{
            //    m_worksheet.Cells[1, i + 1] = dt.Columns[i].ColumnName.ToString();
            //}
            //先给Range对象一个范围为A2开始,Range对象可以给一个CELL的范围,也可以给例如A1到H10这样的范围
            //因为第一行已经写了表头,所以所有数据都应该从A2开始
            range = m_worksheet.get_Range("A4", miss);
            Microsoft.Office.Interop.Excel.Range xlRang = null;
            //iRowCount为实际行数,最大行
            int iRowCount = dt.Rows.Count;
            int iParstedRow = 0, iCurrSize = 0;
            //iEachSize为每次写行的数值,可以自己设置,每次写1000行和每次写2000行大家可以自己测试下效率
            int iEachSize = 1000;
            //iColumnAccount为实际列数,最大列数
            int iColumnAccount = dt.Columns.Count;
            //在内存中声明一个iEachSize×iColumnAccount的数组,iEachSize是每次最大存储的行数,iColumnAccount就是存储的实际列数
            object[,] objVal = new object[iEachSize, iColumnAccount];
            try
            {
                //给进度条赋最大值为实际行数最大值
                iCurrSize = iEachSize;
                while (iParstedRow < iRowCount)
                {
                    if ((iRowCount - iParstedRow) < iEachSize)
                        iCurrSize = iRowCount - iParstedRow;
                    for (int i = 0; i < iCurrSize; i++)//+1  保证最后一行导出
                    {//根据净值,判断是否提完
                        for (int j = 0; j < iColumnAccount; j++)
                        {
                            if (j==0)
                            {
                                objVal[i, j] = "'"+dt.Rows[i + iParstedRow][j].ToString();
                            }
                            else
                            {
                                objVal[i, j] = dt.Rows[i + iParstedRow][j].ToString();
                            }
                        }
                            

                        System.Windows.Forms.Application.DoEvents();
                    }
                    /*
                     * 建议使用设置断点研究下哈
                     * 例如A1到H10的意思是从A到H,第一行到第十行
                     * 下句很关键,要保证获取orkSheet中对应的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("A" + ((int)(iParstedRow + 2)).ToString(), ((char)('A' + iColumnAccount - 1)).ToString() + ((int)(iParstedRow + iCurrSize + 1)).ToString());
                    xlRang = m_worksheet.get_Range("A" + ((int)(iParstedRow + 4)).ToString(), "U" + ((int)(iParstedRow + iCurrSize + 3)).ToString());
                    // 调用Range的Value2属性,把内存中的值赋给Excel
                    xlRang.Value2 = objVal;
                    iParstedRow = iParstedRow + iCurrSize;
                }
                //保存工作表
                m_worksheet.SaveAs(strName, miss, miss, miss, miss, miss, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, miss, miss, miss);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRang);
                xlRang = null;

                //调用方法关闭EXCEL进程,大家可以试下不用的话如果程序不关闭在进程里一直会有EXCEL.EXE这个进程并锁定你的EXCEL表格
                this.KillSpecialExcel(m_excel);

                //MessageBox.Show("数据已经成功导出到:" + saveFileDialog.FileName.ToString(), "导出完成", MessageBoxButtons.OK, MessageBoxIcon.Information);

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

                return;
            }
            // 别忘了在结束程序之前恢复你的环境!
            System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCI;
        }

#region 结束EXCEL.EXE进程的方法
        /// <summary>
        /// 结束EXCEL.EXE进程的方法
        /// </summary>
        /// <param name="m_objExcel">EXCEL对象</param>
        [DllImport("user32.dll", SetLastError = true)]
        static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

        public void KillSpecialExcel(Microsoft.Office.Interop.Excel.Application m_objExcel)
        {
            try
            {
                if (m_objExcel != null)
                {
                    int lpdwProcessId;
                    GetWindowThreadProcessId(new IntPtr(m_objExcel.Hwnd), out lpdwProcessId);

                    System.Diagnostics.Process.GetProcessById(lpdwProcessId).Kill();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值