C# WinForm导出Excel

概述

在.NET应用中,导出Excel是很常见的需求,在我维护的一个应用中就遇到到了这样的需求,需要每月定时从不同的Server的不同数据库中获取Excel报表,手动生成实在是非常蛋疼。导出Excel报表大致有以下三种方式:Office PIA,文件流和NPOI开源库,本文只介绍前两种方式。

Office PIA

.NET开发人员首选的方法,通过COM组件调用Office软件本身来实现文件的创建和读写,但是数据量较大的时候异常缓慢;如下代码所示已经做了优化,将一个二维对象数组赋值到一个单元格区域中(下面的代码中只能用于导出列数不多于26列的数据导出):

public static void ExportToExcel(DataSet dataSet, string outputPath)

{

    Excel.ApplicationClass excel = new Excel.ApplicationClass();

    Excel.Workbook workbook = excel.Workbooks.Add(Type.Missing);

    int sheetIndex = 0;

    foreach (System.Data.DataTable dt in dataSet.Tables)

    {

        object[,] data = new object[dt.Rows.Count + 1, dt.Columns.Count];

        for (int j = 0; j < dt.Columns.Count; j++)

        {

            data[0, j] = dt.Columns[j].ColumnName;

        }

        for (int j = 0; j < dt.Columns.Count; j++)

        {

            for (int i = 0; i < dt.Rows.Count; i++)

            {

                data[i + 1, j] = dt.Rows[i][j];

            }

        }

        string finalColLetter = string.Empty;



        string colCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        int colCharsetLen = colCharset.Length;

        if (dt.Columns.Count > colCharsetLen)

        {

            finalColLetter = colCharset.Substring(

                (dt.Columns.Count - 1) / colCharsetLen - 1, 1);

        }

        finalColLetter += colCharset.Substring(

                (dt.Columns.Count - 1) % colCharsetLen, 1);

        

        Excel.Worksheet sheet = (Excel.Worksheet)workbook.Sheets.Add(

            workbook.Sheets.get_Item(++sheetIndex),

            Type.Missing, 1, Excel.XlSheetType.xlWorksheet);

        sheet.Name = dt.TableName;

        string range = string.Format("A1:{0}{1}", finalColLetter, dt.Rows.Count + 1);

        sheet.get_Range(range, Type.Missing).Value2 = data;

        ((Excel.Range)sheet.Rows[1, Type.Missing]).Font.Bold = true;

    }

    workbook.SaveAs(outputPath, Excel.XlFileFormat.xlWorkbookNormal, Type.Missing,

        Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlExclusive,

        Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

    workbook.Close(true, Type.Missing, Type.Missing);

    workbook = null;

    excel.Quit();

    KillSpecialExcel(excel);

    excel = null;

    GC.Collect();

    GC.WaitForPendingFinalizers();

}



[DllImport("user32.dll", SetLastError = true)]

static extern int GetWindowThreadProcessId(IntPtr hWnd, out int processId);



static void KillSpecialExcel(Excel.Application app)

{

    try

    {

        if (app != null)

        {

            int processId;

            GetWindowThreadProcessId(new IntPtr(app.Hwnd), out processId);

            System.Diagnostics.Process.GetProcessById(processId).Kill();

        }

    }

    catch (Exception ex)

    {

        throw ex;

    }

}

文件流

这种方法的效率明显高于第一种,而且也不需要安装Office,但是导出的xls文件并不符合Excel的格式标准,在打开生成的xls文件时会提示:The file you are trying to open is in a different format that specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file.

public static void ExportToExcel(System.Data.DataSet ds, string path)

{

    StreamWriter sw = null;

    try

    {

        long totalCount = ds.Tables[0].Rows.Count;

        sw = new StreamWriter(path, false, Encoding.Unicode);

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < ds.Tables[0].Columns.Count; i++)

        {

            sb.Append(ds.Tables[0].Columns[i].ColumnName + "\t");

        }

        sb.Append(Environment.NewLine);

        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)

        {

            for (int j = 0; j < ds.Tables[0].Columns.Count; j++)

            {

                sb.Append(ds.Tables[0].Rows[i][j].ToString() + "\t");

            }

            sb.Append(Environment.NewLine);

        }

        sw.Write(sb.ToString());

        sw.Flush();

    }

    catch (IOException ioe)

    {

        throw ioe;

    }

    finally

    {

        if (sw != null)

        {

            sw.Close();

        }

    }

}

你可能感兴趣的:(WinForm)