hanah0310 / Problem-summary

0 stars 0 forks source link

C# 导出 Excel 的各种方法总结 #130

Open hanah0310 opened 4 years ago

hanah0310 commented 4 years ago

https://www.cnblogs.com/Brambling/p/6854731.html

第一种:使用 Microsoft.Office.Interop.Excel.dll

首先需要安装 office 的 excel,然后再找到 Microsoft.Office.Interop.Excel.dll 组件,添加到引用。

View Code View Code 第一种方法性能实在是不敢恭维,而且局限性太多。首先必须要安装 office(如果计算机上面没有的话),而且导出时需要指定文件保存的路径。也可以输出到浏览器下载,当然前提是已经保存写入数据。

第二种:使用 Aspose.Cells.dll

这个 Aspose.Cells 是 Aspose 公司推出的导出 Excel 的控件,不依赖 Office,商业软件,收费的。

可以参考:http://www.cnblogs.com/xiaofengfeng/archive/2012/09/27/2706211.html#top

View Code View Code 设置单元格格式为文本方法:

cell = worksheet.Cells[rowIndex, colIndex + i]; cell.PutValue(colNames[i]); style = cell.GetStyle(); style.Number = 49; // 49(text|@) 表示为文本 cell.SetStyle(style); 第二种方法性能还不错,而且操作也不复杂,可以设置导出时文件保存的路径,还可以保存为流输出到浏览器下载。

第三种:Microsoft.Jet.OLEDB

这种方法操作 Excel 类似于操作数据库。下面先介绍一下连接字符串:

// Excel 2003 版本连接字符串 string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:/xxx.xls;Extended Properties='Excel 8.0;HDR=Yes;IMEX=2;'";

// Excel 2007 以上版本连接字符串 string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:/xxx.xlsx;Extended Properties='Excel 12.0;HDR=Yes;IMEX=2;'"; Provider:驱动程序名称

Data Source:指定 Excel 文件的路径

Extended Properties:Excel 8.0 针对 Excel 2000 及以上版本;Excel 12.0 针对 Excel 2007 及以上版本。

HDR:Yes 表示第一行包含列名,在计算行数时就不包含第一行。NO 则完全相反。

IMEX:0 写入模式;1 读取模式;2 读写模式。如果报错为“不能修改表 sheet1 的设计。它在只读数据库中”,那就去掉这个,问题解决。

View Code View Code 这种方法需要指定一个已经存在的 Excel 文件作为写入数据的模板,不然的话就得使用流创建一个新的 Excel 文件,但是这样是没法识别的,那就需要用到 Microsoft.Office.Interop.Excel.dll 里面的 Microsoft.Office.Interop.Excel.Workbook.SaveCopyAs() 方法另存为一下,这样性能也就更差了。

使用操作命令创建的表都是在最后面的,前面的也没法删除(我是没有找到方法),当然也可以不再创建,直接写入数据也可以。

第四种:NPOI

NPOI 是 POI 项目的.NET版本,它不使用 Office COM 组件,不需要安装 Microsoft Office,目前支持 Office 2003 和 2007 版本。

NPOI 是免费开源的,操作也比较方便,下载地址:http://npoi.codeplex.com/

View Code View Code // 2007 版本创建一个工作簿 IWorkbook workbook = new XSSFWorkbook();

// 2003 版本创建一个工作簿 IWorkbook workbook = new HSSFWorkbook(); PS:操作 2003 版本需要添加 NPOI.dll 的引用,操作 2007 版本需要添加 NPOI.OOXML.dll 的引用。

第五种:GridView

直接使用 GridView 把 DataTable 的数据转换为字符串流,然后输出到浏览器下载。

View Code 这种方式导出 .xlsx 格式的 Excel 文件时,没办法打开。导出 .xls 格式的,会提示文件格式和扩展名不匹配,但是可以打开的。

第六种:DataGrid

其实这一种方法和上面的那一种方法几乎是一样的。

View Code

第七种:直接使用 IO 流

第一种方式,使用文件流在磁盘创建一个 Excel 文件,然后使用流写入数据。

View Code 第二种方式,这种方式就不需要在本地磁盘创建文件了,首先创建一个内存流写入数据,然后输出到浏览器下载。

View Code View Code 这种方法有一个弊端,就是不能设置单元格的格式(至少我是没有找到,是在下输了)。

第八种:EPPlus

EPPlus 是一个使用 Open Office Xml 格式(xlsx)读取和写入 Excel 2007/2010 文件的 .net 库,并且免费开源。

下载地址:http://epplus.codeplex.com/

第一种方式,先使用文件流在磁盘创建一个 Excel 文件,然后打开这个文件写入数据并保存。

View Code 第二种方式,不指定文件,先创建一个 Excel 工作簿写入数据之后,可以选择保存至指定文件(新建文件)、保存为流、获取字节数组输出到浏览器下载。

View Code View Code 这种方法创建文件和输出到浏览器下载都是可以支持 Excel .xlsx 格式的。更多相关属性设置,请参考:

http://www.cnblogs.com/rumeng/p/3785775.html

hanah0310 commented 4 years ago

C#导出数据到Excel的几种方法 https://blog.csdn.net/xueqh/article/details/78366320 C#导出数据到Excel的几种方法

罗卡角 2017-10-27 16:26:55 13866 收藏 9 展开 首先说明,以下几种方法都是将DataTable 中导出数据到Excel 。

1、需要加载固定的Excel模板的方式

第一步,添加简单的 SaveFileDialog,以便将文件保存到合适的位置。 SaveFileDialog SaveDialog = new SaveFileDialog(); SaveDialog.Filter = "Excel 文件(.xls)|.xls|Excel 文件(.xlsx)|.xlsx|所有文件(.)|."; SaveDialog.RestoreDirectory = true; if (SaveDialog.ShowDialog() == DialogResult.OK) { GenerateAttachment(SaveDialog.FileName,dtExport); } 第二步,真正的导出部分的代码 try { //需要添加 Microsoft.Office.Interop.Excel引用 Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application(); if (app == null)//服务器上缺少Excel组件,需要安装Office软件 { return; } app.Visible = false; app.UserControl = true; string strTempPath = System.Windows.Forms.Application.StartupPath + "\Template\Form.xls"; Microsoft.Office.Interop.Excel.Workbooks workbooks = app.Workbooks; Microsoft.Office.Interop.Excel._Workbook workbook = workbooks.Add(strTempPath); //加载模板 Microsoft.Office.Interop.Excel.Sheets sheets = workbook.Sheets; Microsoft.Office.Interop.Excel._Worksheet worksheet = (Microsoft.Office.Interop.Excel._Worksheet)sheets.get_Item(1); //第一个工作薄。 if (worksheet == null)//工作薄中没有工作表 { return; }

            //1、获取数据
            int rowCount = DT.Rows.Count;
            if (rowCount < 1)//没有取到数据
            {
                return;
            }
            //2、写入数据,Excel索引从1开始
            for (int i = 1; i <= rowCount; i++)
            {
                int row_ = 1 + i;  //Excel模板上表头占了1行
                int dt_row = i - 1; //dataTable的行是从0开始的 
                worksheet.Cells[row_, 1] = DT.Rows[dt_row]["itemname"].ToString();
                worksheet.Cells[row_, 2] = DT.Rows[dt_row]["Color"].ToString();
                worksheet.Cells[row_, 3] = DT.Rows[dt_row]["Grade1"].ToString();
               // worksheet.Cells[row_, 4] = DT.Rows[dt_row]["ProAreaName"].ToString();
                worksheet.Cells[row_, 4] = DT.Rows[dt_row]["Quantity"].ToString();
                worksheet.Cells[row_, 5] = DT.Rows[dt_row]["Unit_name"].ToString();
                worksheet.Cells[row_, 6] = DT.Rows[dt_row]["TotalAmt"].ToString();

            }
            worksheet.Cells[DT.Rows.Count + 2, 1] = "合计";
            worksheet.Cells[DT.Rows.Count + 2, 4] = DT.Compute("sum(Quantity)", "");
            worksheet.Cells[DT.Rows.Count + 2, 6] = DT.Compute("sum(TotalAmt)", "");
            //调整Excel的样式。
            //Microsoft.Office.Interop.Excel.Range rg = worksheet.Cells.get_Range("A3", worksheet.Cells[rowCount + 2, 32]);
            //rg.Borders.LineStyle = 1; //单元格加边框
            //worksheet.Columns.AutoFit(); //自动调整列宽

            //隐藏某一行
            //选中部分单元格,把选中的单元格所在的行的Hidden属性设为true
            //worksheet.get_Range(app.Cells[2, 1], app.Cells[2, 32]).EntireRow.Hidden = true;

            //删除某一行
           // worksheet.get_Range(app.Cells[2, 1], app.Cells[2, 32]).EntireRow.Delete(Microsoft.Office.Interop.Excel.XlDirection.xlUp);

            //3、保存生成的Excel文件
            //Missing在System.Reflection命名空间下
            //string savePath = System.Windows.Forms.Application.StartupPath+"/Temp/T1_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls";

            workbook.SaveAs(FileName, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
            //workbook.SaveAs(FileName,FileFormat,Password,WriteResPassword,ReadOnlyRecommended,CreateBackup, AccessMode, ConflictResolution, AddToMru, TextCodepage, TextVisualLayout, Local) 
            //4、按顺序释放资源
            NAR(worksheet);
            NAR(sheets);
            NAR(workbook);
            NAR(workbooks);
            app.Quit();
            NAR(app);
            MessageBox.Show("保存成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
        catch (Exception ex)
        {
           MessageBox.Show("异常,异常信息为:"+ex.ToString(),"");
        }

上述代码中  workbook.SaveAs()方法没有任何问题。开发过程中遇到错误为“值不在预期范围内”,报错位置在此方法,但出错的地方在上面的方法中,有可能是模板,有可能是FileName,总之,不会是这个方法。

第二种,调入内存导出

导入部分的方法

public static void RenderDataTableToExcel(DataTable SourceTable, string FileName) { MemoryStream ms = RenderDataTableToExcel(SourceTable) as MemoryStream; FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.Write); byte[] data = ms.ToArray();

        fs.Write(data, 0, data.Length);
        fs.Flush();
        fs.Close();

        data = null;
        ms = null;
        fs = null;
    }

引用该方法的代码 ,其中strDataOutFile 同样可以用SaveFileDialog string strDataOutFile = TxtDataOutPath.Text.Trim() + TxtDataOutFileName.Text.Trim(); RenderDataTableToExcel(DT_Item, strDataOutFile); 这种方法导出的数据全都是文本格式的,导出的Excel表格种的数据不能进行计算。暂时未找到合适的解决办法。 第三种,直接导出到临时表 protected void ExportExcel(DataTable dt) { if (dt == null || dt.Rows.Count == 0) return; Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();

        if (xlApp == null)
        {
            return;
        }
        System.Globalization.CultureInfo CurrentCI = System.Threading.Thread.CurrentThread.CurrentCulture;
        System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
        Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks;
        Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
        Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];
        Microsoft.Office.Interop.Excel.Range range;
        long totalCount = dt.Rows.Count;
        long rowRead = 0;
        float percent = 0;
        for (int i = 1; i < dt.Columns.Count; i++)
        {
            worksheet.Cells[1, i] = dt.Columns[i].ColumnName;
            range = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[1, i];
            range.Interior.ColorIndex = 15;
            range.Font.Bold = true;
        }
        for (int r = 0; r < dt.Rows.Count; r++)
        {
            for (int i = 1; i < dt.Columns.Count; i++)
            {
                worksheet.Cells[r + 2, i] = dt.Rows[r][i].ToString();
            }
            rowRead++;
            percent = ((float)(100 * rowRead)) / totalCount;
        }
        worksheet.Cells[dt.Rows.Count + 2, 1] = "合计";
        worksheet.Cells[dt.Rows.Count + 2, 5] = textBox2.Text;
        xlApp.Visible = true;