• ASP.NET导出Excel的方法总结


    web导出Excel也不是什么新鲜的话题了,到网上一查,结果一大堆。可是要挑选一个好的、合适的方法也不容易。再加上自己也没有真正的做过这方 面的导出工作,到底选那种方法好呢?最近一个一个方法地试了一边,小结出来给大家做个参考。

    测试题目:通过一个模板,导出Excel文件。(模板结构较复杂,有公式、样式、合并行等)

    (一)、首先想到的是用服务器端的Excel软件com来生成目标Excel
                   
    这个是网上找到介绍最多的方法。这方法不多说了,有需要的可以到网上找,这里简单讲讲。这种方法就是调用服务器端的Excel软件,来读取模板,填写模板 的。就是后台启动Excel来处理的,在进程管理器里可以查看到它的进程。
                     
    方法缺点:服务器端要装Excel软件,处理效率低,容易产生进程无法回收。
                    
    优点:Excel处理功能丰富,多样,可以完成一切的Excel文件处理。

                    下面是在网上找到的一个利用Excel com处理Excel文件的类,自己整理了一下,代码:

    using System;
    using System.Reflection;

    namespace MyExcelClass{
    /// <summary>
    /// ExcelClass
    的摘要说明。
    /// </summary>
    public class ExcelClass
    {
       /// <summary>
       ///
    构建ExcelClass
       /// </summary>
       public ExcelClass()
       {
        this.m_objExcel=new Excel.Application();
       }
       /// <summary>
       ///
    构建ExcelClass
       /// </summary>
       /// <param name="objExcel">Excel.Application</param>
       public ExcelClass(Excel.Application objExcel)
       {
        this.m_objExcel=objExcel;
       }

       /// <summary>
       ///
    列标号
       /// </summary>
       private string AList="ABCDEFGHIJKLMNOPQRSTUVWXYZ";

       /// <summary>
       ///
    获取描述区域的字符
       /// </summary>
       /// <param name="x"></param>
       /// <param name="y"></param>
       /// <returns></returns>
       public string GetAix(int x,int y)
       {
        char [] AChars=AList.ToCharArray();
        if(x>=26){return "";}
        string s="";
        s=s+AChars[x-1].ToString();
        s=s+y.ToString();
        return s;
       }

       /// <summary>
       ///
    给单元格赋值1
       /// </summary>
       /// <param name="x">
    行号</param>
       /// <param name="y">
    列号</param>
       /// <param name="align">
    对齐(CENTERLEFTRIGHT</param>
       /// <param name="text">
    </param>
       public void setValue(int y,int x,string align,string text)
       {
        Excel.Range range=sheet.get_Range(this.GetAix(x,y),miss);
        range.set_Value(miss,text);
        if(align.ToUpper()=="CENTER")
        {
         range.HorizontalAlignment=Excel.XlHAlign.xlHAlignCenter;
        }
        if(align.ToUpper()=="LEFT")
        {
         range.HorizontalAlignment=Excel.XlHAlign.xlHAlignLeft;
        }
        if(align.ToUpper()=="RIGHT")
        {
         range.HorizontalAlignment=Excel.XlHAlign.xlHAlignRight;
        }
       }

       /// <summary>
       ///
    给单元格赋值2
       /// </summary>
       /// <param name="x">
    行号</param>
       /// <param name="y">
    列号</param>
       /// <param name="text">
    </param>
       public void setValue(int y,int x,string text)
       {
        Excel.Range range=sheet.get_Range(this.GetAix(x,y),miss);
        range.set_Value(miss,text);
       }

       /// <summary>
       ///
    给单元格赋值3
       /// </summary>
       /// <param name="x">
    行号</param>
       /// <param name="y">
    列号</param>
       /// <param name="text">
    </param>
       /// <param name="font">
    字符格式</param>
       /// <param name="color">
    颜色</param>
       public void setValue(int y,int x,string text,System.Drawing.Font font,System.Drawing.Color color)
       {
        this.setValue(x,y,text);
        Excel.Range range=sheet.get_Range(this.GetAix(x,y),miss);
        range.Font.Size=font.Size;
        range.Font.Bold=font.Bold;
        range.Font.Color=color;
        range.Font.Name=font.Name;
        range.Font.Italic=font.Italic;
        range.Font.Underline=font.Underline;
       }

       /// <summary>
       ///
    插入新行
       /// </summary>
       /// <param name="y">
    模板行号</param>
       public void insertRow(int y)
       {
        Excel.Range range=sheet.get_Range(GetAix(1,y),GetAix(25,y));
        range.Copy(miss);
        range.Insert(Excel.XlDirection.xlDown,miss);
        range.get_Range(GetAix(1,y),GetAix(25,y));
        range.Select();
        sheet.Paste(miss,miss);

       }

      /// <summary>
       ///
    把剪切内容粘贴到当前区域
       /// </summary>
       public void past()
       {
        string s="a,b,c,d,e,f,g";
        sheet.Paste(sheet.get_Range(this.GetAix(10,10),miss),s);
       }
       /// <summary>
       ///
    设置边框
       /// </summary>
       /// <param name="x1"></param>
       /// <param name="y1"></param>
       /// <param name="x2"></param>
       /// <param name="y2"></param>
       /// <param name="Width"></param>
       public void setBorder(int x1,int y1,int x2,int y2,int Width)
       {
        Excel.Range range=sheet.get_Range(this.GetAix(x1,y1),this.GetAix(x2,y2));
        range.Borders.Weight=Width;
       }
       public void mergeCell(int x1,int y1,int x2,int y2)
       {
        Excel.Range range=sheet.get_Range(this.GetAix(x1,y1),this.GetAix(x2,y2));
        range.Merge(true);
       }

       public Excel.Range getRange(int x1,int y1,int x2,int y2)
       {
        Excel.Range range=sheet.get_Range(this.GetAix(x1,y1),this.GetAix(x2,y2));
        return range;
       }

       private object miss=Missing.Value; //忽略的参数OLENULL
       private Excel.Application m_objExcel;//Excel
    应用程序实例
       private Excel.Workbooks m_objBooks;//
    工作表集合
       private Excel.Workbook m_objBook;//
    当前操作的工作表
       private Excel.Worksheet sheet;//
    当前操作的表格

       public Excel.Worksheet CurrentSheet
       {
        get
        {
         return sheet;
        }
        set
        {
         this.sheet=value;
        }
       }

       public Excel.Workbooks CurrentWorkBooks
       {
        get
        {
         return this.m_objBooks;
        }
        set
        {
         this.m_objBooks=value;
        }
       }

       public Excel.Workbook CurrentWorkBook
       {
        get
        {
         return this.m_objBook;
        }
        set
        {
         this.m_objBook=value;
        }
       }

       /// <summary>
       ///
    打开Excel文件
       /// </summary>
       /// <param name="filename">
    路径</param>
       public void OpenExcelFile(string filename)
       {
        UserControl(false);

        m_objExcel.Workbooks.Open( filename,miss,miss,miss,miss,miss,miss,miss,
                               miss,miss,miss,miss,miss,miss,miss);

        m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;

        m_objBook = m_objExcel.ActiveWorkbook;
        sheet = (Excel.Worksheet)m_objBook.ActiveSheet;
       }
       public void UserControl(bool usercontrol)
       {
        if(m_objExcel==null){return ;}
        m_objExcel.UserControl=usercontrol;
        m_objExcel.DisplayAlerts=usercontrol;
        m_objExcel.Visible = usercontrol;
       }
       public void CreateExceFile()
       {
        UserControl(false);
        m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
        m_objBook = (Excel.Workbook)(m_objBooks.Add(miss));
        sheet = (Excel.Worksheet)m_objBook.ActiveSheet;
       }
       public void SaveAs(string FileName)
       {
        m_objBook.SaveAs(FileName, miss, miss, miss, miss,
         miss, Excel.XlSaveAsAccessMode.xlNoChange,
         Excel.XlSaveConflictResolution.xlLocalSessionChanges,
         miss,miss, miss, miss);
        //m_objBook.Close(false, miss, miss);
       }
       public void ReleaseExcel()
       {
        m_objExcel.Quit();
        System.Runtime.InteropServices.Marshal.ReleaseComObject((object)m_objExcel);
        System.Runtime.InteropServices.Marshal.ReleaseComObject((object)m_objBooks);
        System.Runtime.InteropServices.Marshal.ReleaseComObject((object)m_objBook);
        System.Runtime.InteropServices.Marshal.ReleaseComObject((object)sheet);
        m_objExcel=null;
        m_objBooks=null;
        m_objBook=null;
        sheet=null;
        GC.Collect();
       }

       /////////////////////////////////
       public bool KillAllExcelApp()
       {
        try
        {
         if(m_objExcel != null) // isRunning
    是判断xlApp是怎么启动的flag.
         {
          m_objExcel.Quit();
          System.Runtime.InteropServices.Marshal.ReleaseComObject(m_objExcel);
          //
    释放COM组件,其实就是将其引用计数减1
          //System.Diagnostics.Process theProc;
          foreach(System.Diagnostics.Process theProc in System.Diagnostics.Process.GetProcessesByName("EXCEL"))
          {
           //
    先关闭图形窗口。如果关闭失败...有的时候在状态里看不到图形窗口的excel了,
           //
    但是在进程里仍然有EXCEL.EXE的进程存在,那么就需要杀掉它:p
           if( theProc.CloseMainWindow() == false )
           {
            theProc.Kill();
           }
          }
          m_objExcel = null;
          return true;
         }
        }
        catch
        {
         return false;
        }
        return true;
       }
       /////////////////////////////////////////////
    }
    }

                      当然,使用的时候要先在工程引入Excel com,我用的是11版本。

     

    (二)、利用MSOWC,即是微软的 office web component
                  
    安装office就有安装到这个组件。文件和编程参考在系统盘的Program Files\Common Files\Microsoft Shared\下有Office10或者Office11版本。文件夹中还有帮助文件和例子。
    网上找的一段导出Excel的简短例子:

    //请在项目中引用OWC11(COM组件)

    OWC11.SpreadsheetClass xlsheet =new OWC11.SpreadsheetClass();
    //
    合并 单元格
    xlsheet.get_Range(xlsheet.Cells[1,1],xlsheet.Cells[1,14]).set_MergeCells(true);
    xlsheet.ActiveSheet.Cells[1,1] ="
    一级帐表";
    //
    字体加粗
    xlsheet.get_Range(xlsheet.Cells[1,1],xlsheet.Cells[1,14]).Font.set_Bold(true);
    //
    单元格文本水平居中对齐
    xlsheet.get_Range(xlsheet.Cells[1,1],xlsheet.Cells[1,14]).set_HorizontalAlignment(OWC11.XlHAlign.xlHAlignCenter );
    //
    设置字体大小
    xlsheet.get_Range(xlsheet.Cells[1,1],xlsheet.Cells[1,14]).Font.set_Size(14);
    //
    设置列宽
    xlsheet.get_Range(xlsheet.Cells[1,3],xlsheet.Cells[1,3]).set_ColumnWidth(50);

    //画边框线
    xlsheet.get_Range(xlsheet.Cells[1,1],xlsheet.Cells[10,15]).Borders.set_LineStyle(OWC11.XlLineStyle.xlContinuous );

    //写入数据 (这里可根据需要由DS生成)
    for (int row=2;row<10;row ) //
    注意写入数据时,必须从第一行开始写EXCEL里没有第"0"
    {
    for(int i = 0 ;i< 15 ;i )
    {
    xlsheet.ActiveSheet.Cells[row, i 1] =123.456;
    }
    }
    try
    {
    //
    将数字格式化为金额(要格式化的单元格内的值必须为数值型)
    xlsheet.get_Range(xlsheet.Cells[2,1],xlsheet.Cells[10,15]).set_NumberFormat("
    #,##0.00");
    xlsheet.Export("D:\\ExportToExcel\\TestOWC.xls",OWC11.SheetExportActionEnum.ssExportActionNone,OWC11.SheetExportFormat.ssExportXMLSpreadsheet);
    Response.Write("Export OK");
    }
    catch
    {
    }


                    
    这个方法我没有比较全面的试用过。用的时候,好像没有找到它打开Excel文件的方法,不知道是没有还是我没留心找。我在试用的时候,是用它来设计 Excel表的,要画边框,设置样式等,好像很繁。
    (三)、导出XML类型的Excel文件。其实是一个XML文件。
                  
    这个方法好啊,用起来放心。因为asp.net里面提供了很多丰富易用的xml类,xml处理起来明了,简单。我把原来的Excel文件保存为xml文 件,用做模板。接着就是读写Xml文件了。想这么读就怎么读,想怎么写就怎么写,查找记录、改变属性值方便。
                  
    优点:不用安装Excel等软件,处理灵活,效率高。
                   
    缺点:Excel2000版本不支持xml,不知道其他版本支不支持。我用的是2003版本。
    (四)、用htm文件。
                 
    还好Excel2000支持htm,可以把Excel内容保存到htm中。其实就是旧版本的xml吗。当然,样式和公式也可以用。我正打算用这个方法来 做。(还没有去全面试用,不过自己对html还是很熟的,处理起来应该没问题。)
                  
    优缺点先不说,不过它代替xml在低版本的Excel中兼容。

    (五)、网上也有说用text做中介的。
                   
    可是这种文件表示不了样式,公式等等,格式也很死板。
    (六)、 ado.net
                   
    容易出错,而且操作也不灵活,插入等经常遇到问题,而且不能删除行。比较适用于结构单一的Excel表。

                 ////连接
                Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\dd.xls; Extended Properties="Excel 8.0;HDR=YES;"
                 HDR
    表示是否把第一行当作表头。如果为"NO"则系统或自动给行命名为F1,F2,F3.....
                 ///////
    获取默认的Excel
                 DataTable dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
                tableName = dt.Rows[0][2].ToString().Trim();
                ///
    更新数据
               update [titles$] set F1='dd'
                ///
    插入数据
                INSERT INTO DataTable values(1,'e2')
                ///
    查询数据
               select * from [Sheet1$] where F1=5

               更多可以查看MSDN读取 Excel MSDN 写入Excel

    (六)、也有方法在客户端导出Excel。就是用脚本。
    脚本导出:
    function run(mytb)
    {
    var mysheet=new ActiveXObject("OWC.Spreadsheet");
    with(mysheet)
    {
    DataType = "HTMLData";
    HTMLData =mytb.outerHTML;
    try{
    ActiveSheet.Export("c:\\dxx.xls", 0);
    alert('
    汇出完毕');
    };
    catch (e){
    alert('
    导出Excel表失败,请确定已 安装Excel2000(或更高版本),并且没打开同名xls文件');
    };
    }
    }

    =============================
    补 充:
    最近在导出DataGrid/GridView数据行到Excel的时候,如果文件名为中文的话,就会出现乱码。晕了一个下午,终于找到解决 方法,现记载如下:

    1Response.Clear();
    2    Response.Buffer = true;
    3    Response.Charset = "gb2312";
    4    Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
    5    Response.AppendHeader("content-disposition","attachment;filename=\"" + System.Web.HttpUtility.UrlEncode("
    中文名称",System.Text.Encoding.UTF8) + ".xls\"");
    6    Response.ContentType = "Application/ms-excel";

    3、 身份证号码的问题:存储为字符串
            if (e.

  • 相关阅读:
    govalidator----结构体tag验证
    结构字段验证--validator.v9
    序列化
    案例:8,64,256都是2的阶次方数(8是2的3次方),用Java编写程序来判断一个整数是不是2的阶次方数。
    易错点
    什么是线程与进程?
    对象与实例的区别?
    什么情况下用断言?assert
    垃圾收集器什么时候回收垃圾?
    HashMap 和 HashTable 的区别
  • 原文地址:https://www.cnblogs.com/ldy_ai/p/bimin.html
Copyright © 2020-2023  润新知