打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
[PHP Excel 输出]使用 PHP 输出带格式的 Excel 文件

作者: rardge    时间: 2006-4-25 22:38     标题: [PHP Excel 输出]使用 PHP 输出带格式的 Excel 文件

工作中的一点心得,拿出来分享一下。

用 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}> 来处理。

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
  <Author>Diana</Author>
  <LastAuthor>Diana</LastAuthor>
  <Created>2006-04-25T11:58:52Z</Created>
  <LastSaved>2006-04-25T13:10:20Z</LastSaved>
  <Version>11.5606</Version>
</DocumentProperties>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
  <WindowHeight>12495</WindowHeight>
  <WindowWidth>16035</WindowWidth>
  <WindowTopX>0</WindowTopX>
  <WindowTopY>105</WindowTopY>
  <ProtectStructure>False</ProtectStructure>
  <ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
  <Style ss:ID="Default" ss:Name="Normal">
   <Alignment ss:Vertical="Center"/>
   <Borders/>
   <Font ss:FontName="宋体" x:CharSet="134" ss:Size="12"/>
   <Interior/>
   <NumberFormat/>
   <Protection/>
  </Style>
  <Style ss:ID="s21">
   <Font ss:FontName="宋体" x:CharSet="134" ss:Size="18" ss:Bold="1"/>
  </Style>
  <Style ss:ID="s29">
   <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
   <Borders>
    <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
    <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
    <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
    <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
   </Borders>
  </Style>
  <Style ss:ID="s35">
   <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
   <Borders>
    <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
    <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
    <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
    <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
   </Borders>
   <NumberFormat ss:Format="@"/>
  </Style>
</Styles>
<Worksheet ss:Name="Sheet1">
  <Table ss:ExpandedColumnCount="5" ss:ExpandedRowCount="21" x:FullColumns="1"
   x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="17.25">
   <Column ss:AutoFitWidth="0" ss:Width="36"/>
   <Column ss:AutoFitWidth="0" ss:Width="69"/>
   <Column ss:AutoFitWidth="0" ss:Width="78.75"/>
   <Row ss:Height="22.5">
    <Cell ss:StyleID="s21"><Data ss:Type="String">员工信息表</Data></Cell>
   </Row>
   <Row ss:AutoFitHeight="0"/>
   <Row ss:AutoFitHeight="0">
    <Cell ss:StyleID="s29"><Data ss:Type="String">序号</Data></Cell>
    <Cell ss:StyleID="s29"><Data ss:Type="String">工号</Data></Cell>
    <Cell ss:StyleID="s29"><Data ss:Type="String">姓名</Data></Cell>
    <Cell ss:StyleID="s29"><Data ss:Type="String">性别</Data></Cell>
    <Cell ss:StyleID="s29"><Data ss:Type="String">年龄</Data></Cell>
   </Row>

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

  </Table>
</Worksheet>
</Workbook>

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

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

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

        $emps[1][‘id‘] = ‘00002‘;
        $emps[1][‘name‘] = ‘BBC‘;
        $emps[1][‘sexual‘] = ‘男‘;
        $emps[1][‘age‘] = 23;

        $emps[2][‘id‘] = ‘00003‘;
        $emps[2][‘name‘] = ‘CBA‘;
        $emps[2][‘sexual‘] = ‘女‘;
        $emps[2][‘age‘] = 20;

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

        $smarty->assign(‘Emps‘, $emps);

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

        $smarty->display(‘excel.tpl‘);
?>

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

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

图片附件: [上面那个例子的效果图] 1234567.JPG (2006-4-25 23:15, 29.3 KB) / 该附件被下载次数 19
http://bbs.chinaunix.net/attachment.php?aid=137712


作者: yeff    时间: 2006-4-25 23:01

学习中。。。。。。。。。

作者: imbiss    时间: 2006-4-26 06:35

Template->XML->M$ XSL
不错。

作者: xuzuning    时间: 2006-4-26 10:46

其实你用html+css就可以了

作者: rardge    时间: 2006-4-26 10:56



QUOTE:
原帖由 xuzuning 于 2006-4-26 10:46 发表
其实你用html+css就可以了

不好意思,我对 html 和 css 方面不熟。是不是在浏览器页面上显示,然后用 excel 来导入表格啊?
你是不是 CSDN 的 PHP 版版主?

作者: benxixi    时间: 2006-4-26 17:58

我有完全用php在linux下生成Excel2000的代码(生成的是一个二进制代码),
不需要任何控件
效率还可以,生成一个7M左右的Excel表格在40s左右
可以控制到打印/页码/公式/图形/单元格样式/合并/冻结行等
完全可以定制
BTW:不提供免费代码,是为公司做的一个应用
花了我三个星期的时间.
不过可以提供付费代码(以封装成class,可以直接调用)


[ 本帖最后由 benxixi 于 2006-4-26 18:03 编辑 ]

作者: scf2    时间: 2006-5-4 18:59



QUOTE:
原帖由 benxixi 于 2006-4-26 17:58 发表
我有完全用php在linux下生成Excel2000的代码(生成的是一个二进制代码),
不需要任何控件
效率还可以,生成一个7M左右的Excel表格在40s左右
可以控制到打印/页码/公式/图形/单元格样式/合并/冻结行等
完全可以定 ...

能不能提供个演示啊

作者: 七星剑客    时间: 2006-5-5 08:07



QUOTE:
原帖由 benxixi 于 2006-4-26 17:58 发表
我有完全用php在linux下生成Excel2000的代码(生成的是一个二进制代码),
不需要任何控件
效率还可以,生成一个7M左右的Excel表格在40s左右
可以控制到打印/页码/公式/图形/单元格样式/合并/冻结行等
完全可以定 ...

缺乏共享精神,谴责一个.

作者: benxixi    时间: 2006-5-6 20:57



QUOTE:
原帖由 scf2 于 2006-5-4 18:59 发表


能不能提供个演示啊

呵呵
是公司内部产品,
没法提供演示
不过绝对真实
详细情况可以MSN和QQ联系

作者: linuxdotnet    时间: 2006-5-8 14:46



QUOTE:
原帖由 benxixi 于 2006-4-26 17:58 发表
我有完全用php在linux下生成Excel2000的代码(生成的是一个二进制代码),
不需要任何控件
效率还可以,生成一个7M左右的Excel表格在40s左右
可以控制到打印/页码/公式/图形/单元格样式/合并/冻结行等
完全可以定 ...

能不能给点提示啊...

作者: james.liu    时间: 2006-5-8 14:56

支持lz.嘿嘿

网上有个在线什么类似excel,,都是js+html+css

可能还有xml+xslt,,我没仔细看

之所以说类似excel,完全是因为长得像。

作者: benxixi    时间: 2006-5-9 10:43



QUOTE:
原帖由 linuxdotnet 于 2006-5-8 14:46 发表



能不能给点提示啊...

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

一小段

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

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

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

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

    $reserved = 0x00;
    $format   = $_[3];


    if (isset($_[3]))
    {
        $ixfe = $format->get_xf_index();
    }
    else
    {
        $ixfe = 0x0F;
    }
        $level    = $_[5] || 0;
        if ($level < 0)
    {
            $level = 0;
    }
        if ($level > 7)
        {
                $level = 7;
        }
        $grbit |= $level << 8;
       
    $header = pack("vv", $record, $length);//字段信息

    $data = pack("vvvvvC", $colFirst, $colLast, $coldx, $ixfe, $grbit, $reserved);//实际内容
    //省略存储代码
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
掌握这个万能键,你的办公效率蹭蹭往上涨
Excel 单元格格式大全
8个打印小技巧,让工作效率提升百倍!
Excel中如何让数据有效性不被复制粘贴破坏?简单到没朋友!
Excel教程:巧用Excel批量生成和打印考场座位标签
2012年职称计算机考试试题练习之excel2003模拟试题及答案
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服