Spiga

Asp.net程序中生成Excel报表

2008-04-14 22:22 by 汉广, 4639 visits, 网摘, 编辑
 

   在后台调用excel组件,生成Excel,虽然可以Excel文件进行完全控制,可以生成任何复杂的格式,但是有个很大的缺点,这种方式会产生很多Excel进程很难完全清掉,特别是在出错的时候,可能会使整个服务器崩溃。本文为大家介绍一个C#写的开源组件,并简单说下office2003和以上版本支持的XML格式。

 操作Excel二进制格式

    OpenOffice.org发布过的俩个文档Excel File Format (BIFF8)SpecificationMicrosoft CompoundDocument (OLE2) Format SpecificationExcel的二进制格式做了一个比较详细的说明,依靠这些信息,我们可以直接操作Office二进制格式文档。

  MyXls是一个C#写的开源组件,可以用来生成具有很多表格且包含格式的Excel文件。它提供了一套基于对象的API,非常容易使用。

1,生成一个空的表格

       

1 XlsDocument xls = new XlsDocument(); //创建一个空的Excel文档
2        
3 xls.Send(); //将文档发送到浏览器。

2, 创建一个复杂点表格
 XlsDocument xls = new XlsDocument();
            xls.FileName 
= "Wacky.xls";

            
//添加文件属性
            xls.SummaryInformation.Author = "Tim Erickson"//作者
            xls.SummaryInformation.Subject = "A wacky display of Excel file generation";
            xls.DocumentSummaryInformation.Company 
= "in2bits.org";

            
for (int sheetNumber = 1; sheetNumber <= 5; sheetNumber++)
            
{
                
string sheetName = "Sheet " + sheetNumber;
                
int rowMin = sheetNumber;
                
int rowCount = sheetNumber + 10;
                
int colMin = sheetNumber;
                
int colCount = sheetNumber + 10;
                
//创建5个表格
                Worksheet sheet = xls.Workbook.Worksheets.AddNamed(sheetName);
                Cells cells 
= sheet.Cells;
                
for (int r = 0; r < rowCount; r++)
                
{
                    
if (r == 0)
                    
{
                        
for (int c = 0; c < colCount; c++)
                        
{
                            
//在一行内创建colCount个单元格
                            cells.Add(rowMin + r, colMin + c, "Fld" + (c + 1)).Font.Bold = true;
                        }

                    }

                    
else
                    
{
                        
for (int c = 0; c < colCount; c++)
                        
{
                            
int val = r + c;
                            Cell cell 
= cells.Add(rowMin + r, colMin + c, val);
                            
if (val % 2 != 0)
                            
{
                                cell.Font.FontName 
= "Times New Roman";
                                cell.Font.Underline 
= UnderlineTypes.Double;//给文字下方加一个双下划线
                                cell.Rotation = 45;//单元格文字旋转45度
                            }

                        }

                    }

                }

            }

效果图,一个Excel文件包含五个表格

二 XML格式

office2003或以上版本才支持xml格式,这样可以直接通过一些模板将内容转化为Office可以识别的xml,限于时间,下次再与大家讨论:-)
Add your comment

50 条回复

  1. #1楼 willieQ      2008-04-14 22:38
    不错。。。学习,收藏
      回复  引用  查看    
  2. #2楼 peace      2008-04-14 23:04
    这个处理很好
      回复  引用  查看    
  3. #3楼[楼主] 汉广      2008-04-14 23:10
    @peace
    这俩天正好也在做导出到Excel,看了你的文章才想到写这个的。。。。


      回复  引用  查看    
  4. #4楼 jillzhang      2008-04-14 23:10
    这样的事情很有意义
      回复  引用  查看    
  5. #5楼[楼主] 汉广      2008-04-14 23:16
    @jillzhang
    试用了 MyXls,觉的很好用,而且开源的也可靠,
    发现SourceForge这个东西下载量非常小,所以拿来介绍下:-)
      回复  引用  查看    
  6. #6楼 Ricky81[未注册用户]2008-04-15 00:29
    我记得MS已经正式官方发布了Office的二进制文档格式说明。
      回复  引用    
  7. #7楼 簡簡單單..      2008-04-15 00:36
    不错不错
      回复  引用  查看    
  8. #8楼 生鱼片      2008-04-15 07:07
    MyXLS记住了
      回复  引用  查看    
  9. #9楼 新程金锣      2008-04-15 07:26
    挺好的
      回复  引用  查看    
  10. #10楼 OneCool      2008-04-15 08:15
    ushort fontIndex = BitConverter.ToUInt16(recordData.Get(0, 2).ByteArray, 0);
    ushort formatIndex = BitConverter.ToUInt16(recordData.Get(2, 2).ByteArray, 0);
    //ushort styleIndex = BitConverter.ToUInt16(recordData.Get(4, 2))
    Font font = fonts[fontIndex];

    以前看到过,在读EXCEL文件的时候有错误。
      回复  引用  查看    
  11. #11楼 李战      2008-04-15 08:23
    http://www.cnblogs.com/Emoticons/yoyocici/223852199.gif" alt="" />路过,学习!

      回复  引用  查看    
  12. #12楼 心悦      2008-04-15 09:01
    不错,学习之
      回复  引用  查看    
  13. #13楼 狼Robot      2008-04-15 09:09
    学习
      回复  引用  查看    
  14. #14楼 liu ray[未注册用户]2008-04-15 09:33
    非常好
      回复  引用    
  15. #15楼 小龙3      2008-04-15 09:36
    一直苦恼.NET下没有类似于JAVA下的JExcelApi,现在好了!!

    谢谢博主!!!!
      回复  引用  查看    
  16. #16楼 天生俪姿      2008-04-15 09:44
    8错8错
    呱叽呱叽
      回复  引用  查看    
  17. #17楼 鹏鹏_Lovely      2008-04-15 09:48
    期待你的XML哦。谢啦。
      回复  引用  查看    
  18. #18楼 鹏鹏_Lovely      2008-04-15 10:00
    MyXls————C#写的开源组件。可以给我一份吗,我想要个MyXls组件。
      回复  引用  查看    
  19. #19楼[楼主] 汉广      2008-04-15 10:48
    @鹏鹏_Lovely
    文章里有链接的:-)
    @所有人
    谢谢大家支持
      回复  引用  查看    
  20. #20楼 恋恋风尘      2008-04-15 19:09
    没个文档,没个性能测试数据,实在不放心用在自己的项目中
      回复  引用  查看    
  21. #21楼[楼主] 汉广      2008-04-15 19:44
    @恋恋风尘
    感觉性能还行,可以自己测试下
      回复  引用  查看    
  22. #22楼 Jim~      2008-04-15 22:47
    果然够简单的~~~支持下
      回复  引用  查看    
  23. #23楼 nine425[未注册用户]2008-04-16 10:01
    请问楼主:
    1 XlsDocument xls = new XlsDocument(); //创建一个空的Excel文档
    2
    3 xls.Send(); //将文档发送到浏览器。

    请问xls.Send();如何将文档只发送到IE浏览器中?我试了一下,只提示下载还是打开,可不可以不显示提示直接在IE中打开?
      回复  引用    
  24. #24楼 nine425[未注册用户]2008-04-16 11:07
    我又查了一下MyXls的源码,可以这样发送到浏览器:
    xls.Send(XlsDocument.SendMethods.Inline);
      回复  引用    
  25. #25楼 nine425[未注册用户]2008-04-16 11:11
    再问楼主:
    通过MyXls如何打开一个已存在的xls文档呢?
      回复  引用    
  26. #26楼 nine425[未注册用户]2008-04-16 11:15
    如果我这样写:
    XlsDocument xls = new XlsDocument(@"D:\My Net\WebSite1\xls\test.xls");
    运行时提示错误如下:

    “/WebSite1”应用程序中的服务器错误。
    --------------------------------------------------------------------------------

    value already exists
    参数名: name
    说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

    异常详细信息: System.ArgumentException: value already exists
    参数名: name
      回复  引用    
  27. #27楼[楼主] 汉广      2008-04-16 11:42
    @nine425
    还不支持读操作的。。。。。
      回复  引用  查看    
  28. #28楼 channel139[未注册用户]2008-04-16 12:52
    不错学习之
      回复  引用    
  29. #29楼 nine425[未注册用户]2008-04-16 13:15
    请问:
    xls.Send(XlsDocument.SendMethods.Inline); 是将内容显示在当前页面,那么如何让内容显示在另一个页面呢?
    比如:左右两个框架,点击左框架某个按钮,会在右框架显示相关文件内容。
      回复  引用    
  30. #30楼 nine425[未注册用户]2008-04-16 17:19
    可能我问的问题太简单了点。左框架链接页面显示在右框架,这个我会。我的问题是:如果左框架显示了很多xls文件,这些文件可能分布在服务端众多的不同的目录,而我并未将这些目录在IIS中做成虚拟目录(如果做成虚拟目录,给xlls文件名写个超链接接可以了,但目录实在是太多)。现在我想实现的效果是:点击左框架xls文件名,会在右框架中(或在单独的一个页面,如果不用框架的话)显示该xls文件内容。我的xls文件内容读取方法采用MyXls的HttpContent方法。而MyXls新建xls文件后,采用xls.Send(XlsDocument.SendMethods.Inline); 只能将内容覆盖显示在当前页面,所以想请教楼主能不能让它单独显示在另一个页面呢?
    谢谢!
      回复  引用    
  31. #31楼[楼主] 汉广      2008-04-16 20:21
    @nine425
    xls.Send()方法只是把当前excel文档的二进制流写入当前的输出流,
    xls.Send(XlsDocument.SendMethods.Inline)只是给Http响应加了个
    “Content-Disposition: Inline” Header,它使得浏览器默认处理附件的方式为直接打开,而不是保存。
    关于Content-Disposition的更多信息可以浏览RFC1806
    http://www.ietf.org/rfc/rfc1806.txt" target="_new">http://www.ietf.org/rfc/rfc1806.txt

    至于你说的Feature,建议可以使用Javascript监测左框架的点击事件,驱动右边框架的地址。

    至于读取Excel文件,ADO.net比较好的支持Excel文件读取,可以参考
    http://support.microsoft.com/kb/306572/" target="_new">http://support.microsoft.com/kb/306572/

    欢迎讨论,希望这些信息对你有用:-)
      回复  引用  查看    
  32. #32楼 nine425[未注册用户]2008-04-17 13:02
    谢谢楼主!这些信息很有价值。
    不过,我想要的效果很简单,将xls文档或doc文档直接显示在另一个页面即可,但不通过链接如:http://...//test.doc的方式。直接读取服务端路径的某个office文件,采用二进制流,所以我对MyXls比较感兴趣。
      回复  引用    
  33. #33楼 Justinian[未注册用户]2008-04-24 15:03
    不行,用不来。 使用后打开的excel里全是当前页的一些html编码,而且汉字都是乱码,也没产生5个sheet页,请教博主,我哪里出问题了?
      回复  引用    
  34. #34楼[楼主] 汉广      2008-04-25 10:56
    怎么可能,你把代码贴上来看看
      回复  引用  查看    
  35. #35楼 冷火      2008-04-28 14:15
    我怎知道,怎么合并单元格?
      回复  引用  查看    
  36. #36楼 cepheus[未注册用户]2008-04-28 16:05
    楼主,我想知道怎么设置单元格的宽度?
    我用
    ColumnInfo col = new ColumnInfo(xls, sheet);
    sheet.AddColumnInfo(col);
    col.Width = 5120;
    但是这只能改变第一列的宽度,后面的就变不了了,不知道这是为什么?
      回复  引用    
  37. #37楼 Justinian[未注册用户]2008-04-29 13:52
    我自己使用最简单的代码都出错,

    XlsDocument xls = new XlsDocument();
    xls.Send();

    这样子产生的文档内容为当前页的一些html编码,且汉字成了乱码。
    请教博主,我哪里出问题了?
    我是用vs2008在测。 不知道和这个有没有关系!
      回复  引用    
  38. #38楼 zhangyi[未注册用户]2008-04-29 17:06
    XlsDocument xls = new XlsDocument(path);
    为什么执行到这个地方总有问题 ,我想吧本地xls文件读出来 这样不行吗
      回复  引用    
  39. #39楼 冷火      2008-04-29 17:33
    我知道怎合并单元格了
      回复  引用  查看    
  40. #40楼[楼主] 汉广      2008-04-30 10:16
    对不起,刚看到评论。

    @冷火
    @cepheus
    单元格长度可以这样改变
    ColumnInfo col = new ColumnInfo(xls, sheet);
    cInfo.ColumnIndexStart = 1;
    cInfo.ColumnIndexEnd = 4;
    sheet.AddColumnInfo(col);
    col.Width = 5120;

    @Justinian
    这个程序是2.0的,可能3.5会有问题,
    @zhangyi
    目前不支持读操作
      回复  引用  查看    
  41. #41楼[楼主] 汉广      2008-04-30 10:24
    刚才那段程序敲错了,应该这样 :-)
    ColumnInfo cInfo = new ColumnInfo(xls, sheet);
    cInfo.ColumnIndexStart = 1;
    cInfo.ColumnIndexEnd = 4;
    col.Width = 5120;
    sheet.AddColumnInfo(col);

    ColumnInfo类那俩个属性用来设置所要影响的列。
      回复  引用  查看    
  42. #42楼 LouisWang[未注册用户]2008-06-06 15:23
    这位大哥,你提供的这个开源组件很有用,我正在为这个问题头痛,正好给我解决了,谢谢!
      回复  引用    
  43. #43楼 dot net菜鳥[未注册用户]2008-06-07 18:28
    好東西,有沒有技术文檔?如使用參考之類的?
      回复  引用    
  44. #44楼 郭斌[未注册用户]2008-09-02 10:46
    IE6下,生成Excel文件之后,会有一个空白页,楼主知道怎么把该空白页删除掉吗。IE7下面则没有这个问题
      回复  引用    
  45. #45楼 徐文兵      2008-09-03 14:12
    对了 问一下 行高 怎么 设置阿
      回复  引用  查看    
  46. #46楼 天下鹰      2008-09-03 15:25
    还有就是,隐藏一个不要的列怎么设置呢?

    急需。。。
      回复  引用  查看    
  47. #47楼[楼主] 汉广      2008-10-07 17:02
    @郭斌
    @天下鹰
    @徐文兵
    对不起,前阵子一直没打理博客,没看到各位的留言。
      回复  引用  查看    
  48. #48楼 张新[未注册用户]2009-03-05 18:16
    MergeArea meaA = new MergeArea(1, 2, 3, 4);//一个合并单元格实例(合并第一行、第三例 到 第二行、第四例)
    sheet.AddMergeArea(meaA);
    加上这段代码后生成的XLS不能正常打开,如果去掉以后就可以正常打开了,这什么原因啊,3Q
      回复  引用    
  49. #49楼 猫狼      2009-03-05 22:42
    如何插入分页符啊
      回复  引用  查看    
  50. #50楼 Fy123[未注册用户]2009-03-07 13:26
    如何单元格自动换行?
      回复  引用    



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1153414




相关文章:

相关链接: