免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 57806 | 回复: 19
打印 上一主题 下一主题

[PHP Excel 输出]使用 PHP 输出带格式的 Excel 文件 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-04-25 22:38 |只看该作者 |正序浏览
工作中的一点心得,拿出来分享一下。

用 PHP 生成 Excel 文件早已不是什么难题了,但若生成的 Excel 文件没有格式(边框线、居中、字体等),其实就是生成文本文件再用 Excel 打开而已。
在 Windows 平台下,可能用 COM 组件可以做到这点,但在 Unix 类系统环境下就没这么幸运了。

首先看一下当时这个新闻吧:
http://bbs.chinaunix.net/viewthread.php?tid=204738&highlight=excel [微软发Office免费许可 开放其XML文件格式]
基本上还是要感谢微软,否则白搭。
我做的也就是使用其 XML 格式。注意:也就是说,这种方法生成的文件可能只对 Office 2003 有效。

至于 Excel 的 XML 格式,各位可以自己仔细研究,新建一个工作簿,然后简单的设置一些单元格,输入一些内容,然后选择另存为,保存类型选择“XML表格”即可。
用文本编辑器打开刚才那个 XML 文件,看看它是怎么描述一个单元格的格式的。它也是用 <Style> 标记,分配不同的 id 值,然后在下面进行任意调用。

我这里介绍一个模板的应用,就是先做好 Excel 样表(因为大多数应用都是输出的文件事先已设计好格式了),然后存成“XML表格”格式文件,再用 PHP 配合 Smarty 来输出。
先看模板文件(excel.tpl)(注意,我用的标记是“<{”和“}>”)
在这个例子中,关键就是把循环显示员工信息部分用 <{section}> 来处理。

  1. <?xml version="1.0"?>
  2. <?mso-application progid="Excel.Sheet"?>
  3. <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
  4. xmlns:o="urn:schemas-microsoft-com:office:office"
  5. xmlns:x="urn:schemas-microsoft-com:office:excel"
  6. xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
  7. xmlns:html="http://www.w3.org/TR/REC-html40">
  8. <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
  9.   <Author>Diana</Author>
  10.   <LastAuthor>Diana</LastAuthor>
  11.   <Created>2006-04-25T11:58:52Z</Created>
  12.   <LastSaved>2006-04-25T13:10:20Z</LastSaved>
  13.   <Version>11.5606</Version>
  14. </DocumentProperties>
  15. <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
  16.   <WindowHeight>12495</WindowHeight>
  17.   <WindowWidth>16035</WindowWidth>
  18.   <WindowTopX>0</WindowTopX>
  19.   <WindowTopY>105</WindowTopY>
  20.   <ProtectStructure>False</ProtectStructure>
  21.   <ProtectWindows>False</ProtectWindows>
  22. </ExcelWorkbook>
  23. <Styles>
  24.   <Style ss:ID="Default" ss:Name="Normal">
  25.    <Alignment ss:Vertical="Center"/>
  26.    <Borders/>
  27.    <Font ss:FontName="宋体" x:CharSet="134" ss:Size="12"/>
  28.    <Interior/>
  29.    <NumberFormat/>
  30.    <Protection/>
  31.   </Style>
  32.   <Style ss:ID="s21">
  33.    <Font ss:FontName="宋体" x:CharSet="134" ss:Size="18" ss:Bold="1"/>
  34.   </Style>
  35.   <Style ss:ID="s29">
  36.    <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
  37.    <Borders>
  38.     <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
  39.     <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
  40.     <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
  41.     <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
  42.    </Borders>
  43.   </Style>
  44.   <Style ss:ID="s35">
  45.    <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
  46.    <Borders>
  47.     <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
  48.     <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
  49.     <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
  50.     <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
  51.    </Borders>
  52.    <NumberFormat ss:Format="@"/>
  53.   </Style>
  54. </Styles>
  55. <Worksheet ss:Name="Sheet1">
  56.   <Table ss:ExpandedColumnCount="5" ss:ExpandedRowCount="21" x:FullColumns="1"
  57.    x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="17.25">
  58.    <Column ss:AutoFitWidth="0" ss:Width="36"/>
  59.    <Column ss:AutoFitWidth="0" ss:Width="69"/>
  60.    <Column ss:AutoFitWidth="0" ss:Width="78.75"/>
  61.    <Row ss:Height="22.5">
  62.     <Cell ss:StyleID="s21"><Data ss:Type="String">员工信息表</Data></Cell>
  63.    </Row>
  64.    <Row ss:AutoFitHeight="0"/>
  65.    <Row ss:AutoFitHeight="0">
  66.     <Cell ss:StyleID="s29"><Data ss:Type="String">序号</Data></Cell>
  67.     <Cell ss:StyleID="s29"><Data ss:Type="String">工号</Data></Cell>
  68.     <Cell ss:StyleID="s29"><Data ss:Type="String">姓名</Data></Cell>
  69.     <Cell ss:StyleID="s29"><Data ss:Type="String">性别</Data></Cell>
  70.     <Cell ss:StyleID="s29"><Data ss:Type="String">年龄</Data></Cell>
  71.    </Row>

  72.    <{* 在这里对要循环输出的数据使用 section 处理。*}>
  73.    <{section name=list loop=$Emps}>
  74.    <Row ss:AutoFitHeight="0">
  75.     <Cell ss:StyleID="s29"><Data ss:Type="Number"><{$smarty.section.customer.rownum}></Data></Cell>
  76.     <Cell ss:StyleID="s35"><Data ss:Type="String"><{$Emps[list].id}></Data></Cell>
  77.     <Cell ss:StyleID="s29"><Data ss:Type="String"><{$Emps[list].name}></Data></Cell>
  78.     <Cell ss:StyleID="s29"><Data ss:Type="String"><{$Emps[list].sexual}></Data></Cell>
  79.     <Cell ss:StyleID="s29"><Data ss:Type="Number"><{$Emps[list].age}></Data></Cell>
  80.    </Row>
  81.    <{/section}>

  82.   </Table>
  83. </Worksheet>
  84. </Workbook>
复制代码

不一定要和我上面这个一模一样,以上我经过少许删减,比如我把最后的 <WorksheetOptions> 段给删掉了。

配套的 PHP 测试程序(excel.php):

  1. <?php
  2.         // 实验资料,实际作业中,这里应该是从数据库取得资料
  3.         $emps[0]['id'] = '00001';
  4.         $emps[0]['name'] = 'ABC';
  5.         $emps[0]['sexual'] = '男';
  6.         $emps[0]['age'] = 28;

  7.         $emps[1]['id'] = '00002';
  8.         $emps[1]['name'] = 'BBC';
  9.         $emps[1]['sexual'] = '男';
  10.         $emps[1]['age'] = 23;

  11.         $emps[2]['id'] = '00003';
  12.         $emps[2]['name'] = 'CBA';
  13.         $emps[2]['sexual'] = '女';
  14.         $emps[2]['age'] = 20;

  15.         ini_set('include_path', '/data/website/htdocs/includes');
  16.         require_once('class.Smarty.php');
  17.         $smarty = new mySmarty();

  18.         $smarty->assign('Emps', $emps);

  19.         // 输出文件头,表明是要输出 excel 文件
  20.         header("Content-type: application/vnd.ms-excel");
  21.         header("Content-Disposition: attachment; filename=test.xml"); //<----- 这里,改成 test.xls 也可以,这样就可以直接用 Excel 打开了。不过本质还是 xml,用记事本打开就知道了。所以打开后,再另存一下,存为真正的 xls 格式。

  22.         $smarty->display('excel.tpl');
  23. ?>
复制代码


完工,放到服务器上跑一下吧。
麻烦的地方,就是 Excel 样表转换成 XML 并修改成 Smarty 模板那一步。
我上面那个例子相对来说简单,因为格式比较单一。更复杂点的报表就要麻烦点了,要在模板中一个个单元格自己去放置 StyleID 值了。
不过,总算能输出一份漂亮的带格式的 Excel 了,这点辛苦还是值得的。

[ 本帖最后由 rardge 于 2006-4-25 23:15 编辑 ]

1234567.JPG (29.3 KB, 下载次数: 433)

上面那个例子的效果图

上面那个例子的效果图

论坛徽章:
0
20 [报告]
发表于 2012-04-14 17:41 |只看该作者
不错    支持一下楼主    楼主辛苦了

论坛徽章:
0
19 [报告]
发表于 2008-11-02 22:17 |只看该作者

论坛徽章:
0
18 [报告]
发表于 2008-10-31 10:43 |只看该作者
xml 是linux下word  xml的最好解决办法, 通过自定义style  可以达到所有你想要的效果。

论坛徽章:
0
17 [报告]
发表于 2008-10-31 10:29 |只看该作者

论坛徽章:
0
16 [报告]
发表于 2007-12-21 22:22 |只看该作者
不错不错,顶一下.

论坛徽章:
0
15 [报告]
发表于 2007-12-21 21:28 |只看该作者
学习中^

论坛徽章:
0
14 [报告]
发表于 2007-12-20 17:49 |只看该作者

回复 #6 benxixi 的帖子

你说的这种代码很久之前网上就有了。一个老外写的。不过没有继续更新了!BUG比较多!使用起来也不太方便
支持单元格颜色字体及公式等。

[ 本帖最后由 dancebear 于 2007-12-20 17:51 编辑 ]

[PHP写execl类库]php_writeexcel-0.3.0.tar.gz

70.75 KB, 下载次数: 384

论坛徽章:
0
13 [报告]
发表于 2007-12-20 11:00 |只看该作者
也可以用php->xml->xslt->excel的纯xml解决办法

论坛徽章:
0
12 [报告]
发表于 2006-05-09 10:43 |只看该作者
原帖由 linuxdotnet 于 2006-5-8 14:46 发表



能不能给点提示啊...



就是要知道详细的excel格式
excel一般是这样做对应
一个字段记录位置,一个记录允许的长度,一个记录字段实际内容
再把相应的转换成二进制
最后一起生成一个文件即可

一小段



  1. function _store_colinfo($_)
  2. {
  3.     $record = 0x007D; //位置
  4.     $length = 0x000B; //允许长度

  5.     $colFirst = $_[0] ? $_[0]: 0;   //第一列
  6.     $colLast  = $_[1] ? $_[1]: 0;    //最后一列
  7.     $width    = $_[2] ? $_[2]: 8.43;//列宽
  8.     if ($width < 1)
  9.     {
  10.         $pixels = int($width *12);
  11.     }
  12.     else
  13.     {
  14.         $pixels = int($width *7 ) +5;
  15.     }

  16.     $coldx    = int($pixels *256/7);

  17.     $grbit           = $_[4] || 0;

  18.     $reserved = 0x00;
  19.     $format   = $_[3];


  20.     if (isset($_[3]))
  21.     {
  22.         $ixfe = $format->get_xf_index();
  23.     }
  24.     else
  25.     {
  26.         $ixfe = 0x0F;
  27.     }
  28.         $level    = $_[5] || 0;
  29.         if ($level < 0)
  30.     {
  31.             $level = 0;
  32.     }
  33.         if ($level > 7)
  34.         {
  35.                 $level = 7;
  36.         }
  37.         $grbit |= $level << 8;
  38.        
  39.     $header = pack("vv", $record, $length);//字段信息

  40.     $data = pack("vvvvvC", $colFirst, $colLast, $coldx, $ixfe, $grbit, $reserved);//实际内容
  41.     //省略存储代码
  42. }
复制代码

[ 本帖最后由 benxixi 于 2006-5-9 10:48 编辑 ]
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP