汉广

常怀恭敬之心
随笔 - 16, 文章 - 0, 评论 - 134, 引用 - 2
数据加载中……

Asp.net程序中生成Excel报表

 

   在后台调用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,限于时间,下次再与大家讨论:-)
Tag标签: asp.net ,excel

posted on 2008-04-14 22:22 汉广 阅读(3536) 评论(43)  编辑 收藏 所属分类: Asp.net

评论

#1楼    回复  引用  查看    

不错。。。学习,收藏
2008-04-14 22:38 | willieQ      

#2楼    回复  引用  查看    

这个处理很好
2008-04-14 23:04 | peace      

#3楼 [楼主]   回复  引用  查看    

@peace
这俩天正好也在做导出到Excel,看了你的文章才想到写这个的。。。。


2008-04-14 23:10 | 汉广      

#4楼    回复  引用  查看    

这样的事情很有意义
2008-04-14 23:10 | jillzhang      

#5楼 [楼主]   回复  引用  查看    

@jillzhang
试用了 MyXls,觉的很好用,而且开源的也可靠,
发现SourceForge这个东西下载量非常小,所以拿来介绍下:-)
2008-04-14 23:16 | 汉广      

#6楼    回复  引用    

我记得MS已经正式官方发布了Office的二进制文档格式说明。
2008-04-15 00:29 | Ricky81 [未注册用户]

#7楼    回复  引用  查看    

不错不错
2008-04-15 00:36 | 簡簡單單..      

#8楼    回复  引用  查看    

MyXLS记住了
2008-04-15 07:07 | 生鱼片      

#9楼    回复  引用  查看    

挺好的
2008-04-15 07:26 | 新程金锣      

#10楼    回复  引用  查看    

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文件的时候有错误。
2008-04-15 08:15 | OneCool      

#11楼    回复  引用  查看    

路过,学习!

2008-04-15 08:23 | 李战      

#12楼    回复  引用  查看    

不错,学习之
2008-04-15 09:01 | 心悦      

#13楼    回复  引用  查看    

学习
2008-04-15 09:09 | 狼Robot      

#14楼    回复  引用    

非常好
2008-04-15 09:33 | liu ray [未注册用户]

#15楼    回复  引用  查看    

一直苦恼.NET下没有类似于JAVA下的JExcelApi,现在好了!!

谢谢博主!!!!
2008-04-15 09:36 | 小龙3      

#16楼    回复  引用  查看    

8错8错
呱叽呱叽
2008-04-15 09:44 | 天生俪姿      

#17楼    回复  引用  查看    

期待你的XML哦。谢啦。
2008-04-15 09:48 | 鹏鹏_Lovely      

#18楼    回复  引用  查看    

MyXls————C#写的开源组件。可以给我一份吗,我想要个MyXls组件。
2008-04-15 10:00 | 鹏鹏_Lovely      

#19楼 [楼主]   回复  引用  查看    

@鹏鹏_Lovely
文章里有链接的:-)
@所有人
谢谢大家支持
2008-04-15 10:48 | 汉广      

#20楼    回复  引用  查看    

没个文档,没个性能测试数据,实在不放心用在自己的项目中
2008-04-15 19:09 | 恋恋风尘      

#21楼 [楼主]   回复  引用  查看    

@恋恋风尘
感觉性能还行,可以自己测试下
2008-04-15 19:44 | 汉广      

#22楼    回复  引用  查看    

果然够简单的~~~支持下
2008-04-15 22:47 | Jim~      

#23楼    回复  引用    

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

请问xls.Send();如何将文档只发送到IE浏览器中?我试了一下,只提示下载还是打开,可不可以不显示提示直接在IE中打开?
2008-04-16 10:01 | nine425 [未注册用户]

#24楼    回复  引用    

我又查了一下MyXls的源码,可以这样发送到浏览器:
xls.Send(XlsDocument.SendMethods.Inline);
2008-04-16 11:07 | nine425 [未注册用户]

#25楼    回复  引用    

再问楼主:
通过MyXls如何打开一个已存在的xls文档呢?
2008-04-16 11:11 | nine425 [未注册用户]

#26楼    回复  引用    

如果我这样写:
XlsDocument xls = new XlsDocument(@"D:\My Net\WebSite1\xls\test.xls");
运行时提示错误如下:

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

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

异常详细信息: System.ArgumentException: value already exists
参数名: name
2008-04-16 11:15 | nine425 [未注册用户]

#27楼 [楼主]   回复  引用  查看    

@nine425
还不支持读操作的。。。。。
2008-04-16 11:42 | 汉广      

#28楼    回复  引用    

不错学习之
2008-04-16 12:52 | channel139 [未注册用户]

#29楼    回复  引用    

请问:
xls.Send(XlsDocument.SendMethods.Inline); 是将内容显示在当前页面,那么如何让内容显示在另一个页面呢?
比如:左右两个框架,点击左框架某个按钮,会在右框架显示相关文件内容。
2008-04-16 13:15 | nine425 [未注册用户]

#30楼    回复  引用    

可能我问的问题太简单了点。左框架链接页面显示在右框架,这个我会。我的问题是:如果左框架显示了很多xls文件,这些文件可能分布在服务端众多的不同的目录,而我并未将这些目录在IIS中做成虚拟目录(如果做成虚拟目录,给xlls文件名写个超链接接可以了,但目录实在是太多)。现在我想实现的效果是:点击左框架xls文件名,会在右框架中(或在单独的一个页面,如果不用框架的话)显示该xls文件内容。我的xls文件内容读取方法采用MyXls的HttpContent方法。而MyXls新建xls文件后,采用xls.Send(XlsDocument.SendMethods.Inline); 只能将内容覆盖显示在当前页面,所以想请教楼主能不能让它单独显示在另一个页面呢?
谢谢!
2008-04-16 17:19 | nine425 [未注册用户]

#31楼 [楼主]   回复  引用  查看    

@nine425
xls.Send()方法只是把当前excel文档的二进制流写入当前的输出流,
xls.Send(XlsDocument.SendMethods.Inline)只是给Http响应加了个
“Content-Disposition: Inline” Header,它使得浏览器默认处理附件的方式为直接打开,而不是保存。
关于Content-Disposition的更多信息可以浏览RFC1806
http://www.ietf.org/rfc/rfc1806.txt

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

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

欢迎讨论,希望这些信息对你有用:-)
2008-04-16 20:21 | 汉广      

#32楼    回复  引用    

谢谢楼主!这些信息很有价值。
不过,我想要的效果很简单,将xls文档或doc文档直接显示在另一个页面即可,但不通过链接如:http://...//test.doc的方式。直接读取服务端路径的某个office文件,采用二进制流,所以我对MyXls比较感兴趣。
2008-04-17 13:02 | nine425 [未注册用户]

#33楼    回复  引用    

不行,用不来。 使用后打开的excel里全是当前页的一些html编码,而且汉字都是乱码,也没产生5个sheet页,请教博主,我哪里出问题了?
2008-04-24 15:03 | Justinian [未注册用户]

#34楼 [楼主]   回复  引用  查看    

怎么可能,你把代码贴上来看看
2008-04-25 10:56 | 汉广      

#35楼    回复  引用  查看    

我怎知道,怎么合并单元格?
2008-04-28 14:15 | 冷火      

#36楼    回复  引用    

楼主,我想知道怎么设置单元格的宽度?
我用
ColumnInfo col = new ColumnInfo(xls, sheet);
sheet.AddColumnInfo(col);
col.Width = 5120;
但是这只能改变第一列的宽度,后面的就变不了了,不知道这是为什么?
2008-04-28 16:05 | cepheus [未注册用户]

#37楼    回复  引用    

我自己使用最简单的代码都出错,

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

这样子产生的文档内容为当前页的一些html编码,且汉字成了乱码。
请教博主,我哪里出问题了?
我是用vs2008在测。 不知道和这个有没有关系!
2008-04-29 13:52 | Justinian [未注册用户]

#38楼    回复  引用    

XlsDocument xls = new XlsDocument(path);
为什么执行到这个地方总有问题 ,我想吧本地xls文件读出来 这样不行吗
2008-04-29 17:06 | zhangyi [未注册用户]

#39楼    回复  引用  查看    

我知道怎合并单元格了
2008-04-29 17:33 | 冷火      

#40楼 [楼主]   回复  引用  查看    

对不起,刚看到评论。

@冷火
@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
目前不支持读操作
2008-04-30 10:16 | 汉广      

#41楼 [楼主]   回复  引用  查看    

刚才那段程序敲错了,应该这样 :-)
ColumnInfo cInfo = new ColumnInfo(xls, sheet);
cInfo.ColumnIndexStart = 1;
cInfo.ColumnIndexEnd = 4;
col.Width = 5120;
sheet.AddColumnInfo(col);

ColumnInfo类那俩个属性用来设置所要影响的列。
2008-04-30 10:24 | 汉广      

#42楼    回复  引用    

这位大哥,你提供的这个开源组件很有用,我正在为这个问题头痛,正好给我解决了,谢谢!
2008-06-06 15:23 | LouisWang [未注册用户]

#43楼    回复  引用    

好東西,有沒有技术文檔?如使用參考之類的?
2008-06-07 18:28 | dot net菜鳥 [未注册用户]