php excel类(解决中文乱码问题,支持多工作薄) 数据分卷技术 附带Demo

1.<?php   
2./**  
3. * @desc excel接口  
4. * @author mengdejun  
5. */  
6.interface  IExcel   
7.{   
8.        //导入excel   
9.        public function import($fileName,$convert_callback_function=null);   
10.        //导出excel   
11.        public function export($fileName="excel");   
12.        //添加行   
13.        public function addRow(array $array,$sheet="sheet1");   
14.        //添加表头   
15.        public function addHead(array $array,$sheet="sheet1");   
16.        //添加工作簿   
17.        public function  addSheet($sheet);   
18.        //释放资源   
19.        public function release();   
20.}   
21.?>  

XmlExcel.php
1.<?php   
2.include_once ('IExcel.php');   
3./**  
4. * @desc php生成excel类函数 支持导入 导出 多工作薄(数据分卷技术)  
5. * @filesource XmlExcel.php  
6. * @author mengdejun  
7. * @date 20100801  
8. * @version 1.8.1  
9. */  
10.if(!defined("CHARSET")):define("CHARSET","UTF-8");endif;   
11.if(!defined("VERSION")):define("VERSION","12.00");endif;   
12.if(!defined("THIS_VERSION")):define("THIS_VERSION","1.8.1");endif;   
13.if(!defined("NULL")):define("NULL",null);endif;   
14.class XmlExcel implements IExcel   
15.{   
16.    private $header = "<?xml version=\"1.0\" encoding=\"%s\"?>\n<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\" 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\">";   
17.    private $documentInfo="<DocumentProperties xmlns=\"urn:schemas-microsoft-com:office:office\"><Author>{author}</Author><Created>{time}</Created><Company>{company}</Company><Version>{version}</Version></DocumentProperties>";   
18.    private $footer = "</Workbook>";   
19.    private $align_left="<Style ss:ID=\"s62\"><Alignment ss:Horizontal=\"Left\" ss:Vertical=\"Center\"/></Style>";   
20.    private $align_center="<Style ss:ID=\"s63\"><Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\"/></Style>";   
21.    private $align_right="<Style ss:ID=\"s64\"><Alignment ss:Horizontal=\"Right\" ss:Vertical=\"Center\"/></Style>";   
22.    private $align_bold="<Style ss:ID=\"s65\"><Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\"/><Font ss:FontName=\"宋体\" x:CharSet=\"134\" ss:Size=\"12\" ss:Color=\"#000000\" ss:Bold=\"1\"/></Style>";   
23.    private $align_default="<Style ss:ID=\"Default\" ss:Name=\"Normal\"><Alignment ss:Horizontal=\"%s\" ss:Vertical=\"Center\"/><Borders/><Font ss:FontName=\"宋体\" x:CharSet=\"134\" ss:Size=\"11\" ss:Color=\"#000000\"/><Interior/><NumberFormat/><Protection/></Style>";   
24.    private $charset=CHARSET;   
25.    private $convert="convert";   
26.    private static $pre_workBook=NULL;   
27.    private $_line=NULL;   
28.    private $_column=NULL;   
29.    private $_columnType=NULL;   
30.    private $_styles=NULL;   
31.    private $_style=NULL;   
32.    private $_title=NULL;   
33.    private $_align="Left";   
34.    private $defaultHeight=13.5;   
35.    private $defaultWidth=54;   
36.    private $_sheets=NULL;   
37.    private $_heads=NULL;   
38.    /**  
39.     * @desc 构造方法 PHP5.X  
40.     * @param string $charset 字符编码  
41.     */  
42.    public function __construct($charset = 'UTF-8')   
43.    {   
44.        $this->charset=$charset;   
45.    }   
46.    /**  
47.     * @desc 构造方法 PHP4.X  
48.     * @param string $charset 字符编码  
49.     */  
50.    public function XmlExcel($charset = 'UTF-8')   
51.    {   
52.        $this->charset=$charset;   
53.    }   
54.    /**  
55.     * @desc 析构方法  
56.     */  
57.    public function __destruct(){}   
58.    /**  
59.     * @desc 释放可用资源  
60.     * @return null  
61.     */  
62.    public function release()   
63.    {   
64.        unset($this->_line,$this->_column,$this->_heads,$this->_sheets,$this->_styles,$this->_style,$this->_title,self::$pre_workBook);   
65.    }   
66.    /**  
67.     * @desc 数组行转换函数  
68.     * @param array $array  
69.     */  
70.    protected function getLine(array $array)   
71.    {   
72.        $_temp="<Row ss:AutoFitHeight=\"0\">";   
73.            foreach($array as $key=>$val):   
74.                #读取指定数据类型,默认String   
75.                $_type=!emptyempty($this->_columnType)&&isset($this->_columnType)?!emptyempty($this->_columnType[$key])&&isset($this->_columnType)?$this->_columnType[$key]:"String":"String";   
76.                $_temp.="<Cell><Data ss:Type=\"{$_type}\">{$this->convert($val)}</Data></Cell>";   
77.            endforeach;   
78.        $_temp.="</Row>";   
79.        return $_temp;   
80.    }   
81.    /**  
82.     * @desc 添加表格头,默认的第一个数组将作为表头  
83.     * @param array $array  
84.     * @param string $sheet 工作表名  
85.     * @exception $array 不能为空  
86.     */  
87.    public function addHead(array $array, $sheet = "sheet1")   
88.    {   
89.        $this->_line[$sheet][0]=$this->getLine($array);   
90.        $this->_title[$sheet]['width']=count($array)-1;   
91.        $this->_sheets[]=$sheet;   
92.        $this->_heads[$sheet][0]=$array;   
93.    }   
94.    /**  
95.     * @desc 添加行  
96.     * @param array $array  
97.     * @param string $sheet  
98.     */  
99.    public function addRow(array $array, $sheet = "sheet1",$isErrorReport=true)   
100.    {   
101.        if($isErrorReport):   
102.            if(emptyempty($array)||!isset($array)||count($array)==0):   
103.                exit("data can't null'");   
104.            else:   
105.                $this->_line[$sheet][]=$this->getLine($array);   
106.            endif;   
107.        else:   
108.            $this->_line[$sheet][]=$this->getLine($array);   
109.        endif;   
110.    }   
111.    /**  
112.     * @desc 设置工作簿的表头对象  
113.     * @param $head 表头数据  
114.     * @param $sheet 工作簿名称   
115.     */  
116.    public function setSheetHead(array $head,$sheet="Sheet1")   
117.    {   
118.        $this->_line[$sheet][]=$this->getLine($head);   
119.    }   
120.    /**  
121.     * @desc 添加多行 支持嵌套数组  
122.     * @param array $array  
123.     * @param unknown_type $sheet  
124.     */  
125.    public function addRows(array $array,$sheet = "Sheet1")   
126.    {   
127.        foreach($array as $value):   
128.            if(is_array($value)):   
129.                $this->addRow($value,$sheet);   
130.            else:   
131.                $this->addRow($array,$sheet);   
132.            endif;   
133.        endforeach;   
134.    }   
135.    /**  
136.     * @desc 获取制定工作薄的列宽度  
137.     * @param @sheet 工作薄名称  
138.     */  
139.    public function getColumnLength($sheet="Sheet1")   
140.    {   
141.        return $this->_title[$sheet]['width'];   
142.    }   
143.    /**  
144.     * @desc 添加工作薄  
145.     * @param unknown_type unknown_type $sheet  
146.     */  
147.    public function addSheet($sheet,$array=array())   
148.    {   
149.        $this->_line[$sheet][]=$array;   
150.    }   
151.    /**  
152.     * @desc 工作薄添加标题  
153.     * @param string $str 标题  
154.     * @param string $sheet 工作薄名  
155.     */  
156.    public function addTitle($str,$sheet="Sheet1")   
157.    {   
158.        $str=$this->convert($str);   
159.        $this->_title[$sheet]['title']="<Row ss:AutoFitHeight=\"0\" ss:StyleID=\"s65\"><Cell ss:MergeAcross=\"{num}\"><Data ss:Type=\"String\">{$str}</Data></Cell></Row>";   
160.    }   
161.    /**  
162.     * @desc excel导出  
163.     * @param string $fileName 导出的文件名  
164.     */  
165.    public function export($fileName = "excel",$isConvert=false)   
166.    {   
167.        if($isConvert):   
168.            $fileName=$this->getConvertString($fileName);   
169.        endif;   
170.        header("Content-Type: application/vnd.ms-excel; charset=" . $this->charset);   
171.        header("Content-Disposition:attachment; filename=\"{$fileName}.xls\"");   
172.        echo stripslashes(sprintf($this->header, $this->charset));   
173.        echo str_replace("{company}","xiaomeng online",str_replace("{time}",date("Y-m-dH:i:s",time()),str_replace("{author}","mengdejun",str_replace("{version}",VERSION,$this->documentInfo))));   
174.        echo "<Styles>";   
175.        echo stripslashes(sprintf($this->align_default, $this->_align));   
176.        echo $this->align_left;   
177.        echo $this->align_right;   
178.        echo $this->align_center;   
179.        echo $this->align_bold;   
180.        echo "</Styles>";   
181.        $_hasData=count($this->_line)==0?false:true;   
182.        if($_hasData):   
183.            #有数据,解析数组对象到excel表格   
184.            foreach($this->_line as $key=>$value):   
185.            echo "<Worksheet ss:Name=\"{$this->convert($key)}\"><Table ss:DefaultColumnWidth=\"{$this->defaultWidth}\" ss:DefaultRowHeight=\"{$this->defaultHeight}\">";   
186.                #列样式和宽度   
187.                if(isset($this->_column[$key]['style_width'])):   
188.                    foreach($this->_column[$key]['style_width'] as $s_key=>$s_value):   
189.                        echo "<Column ss:Index=\"{$s_key}\" ss:AutoFitWidth=\"1\" ss:Width=\"$s_value\"/>";   
190.                    endforeach;   
191.                endif;   
192.                #表格标题   
193.                if(!emptyempty($this->_title[$key]['title'])):   
194.                    echo str_replace("{num}",$this->_title[$key]['width'],$this->_title[$key]['title']);   
195.                endif;   
196.                #单元格   
197.                foreach($value as $_v):   
198.                    echo $_v;   
199.                endforeach;   
200.            echo "</Table></Worksheet>";   
201.            endforeach;   
202.            #加载标准工作薄(默认三个工作簿)   
203.            $length=count($this->_line);   
204.            while($length<3):   
205.                $length++;   
206.                echo "<Worksheet ss:Name=\"Sheet{$length}\"><Table></Table></Worksheet>";   
207.            endwhile;   
208.        else:   
209.             #无数据,添加默认工作簿和数据支持(错误处理:文件读取失败)   
210.             for($index=1;$index<=3;$index++):   
211.                echo "<Worksheet ss:Name=\"Sheet{$index}\"><Table></Table></Worksheet>";   
212.             endfor;   
213.        endif;   
214.        echo $this->footer;   
215.    }   
216.    /**  
217.     * @desc excel导入函数,注该函数的文件名必须是非中文  
218.     * @param unknown_type $fileName 导入的文件  
219.     * @param unknown_type $convert_callback_function 回调函数 支持编码转换,需返回转换后的字符串  
220.     * @return 三维数组,分别对应 工作薄/行/单元格  
221.     */  
222.    public function import($fileName,$convert_callback_function=null)   
223.    {   
224.        $xls=simplexml_load_file($fileName);   
225.        $is_convert=!emptyempty($convert_callback_function)&&function_exists($convert_callback_function);   
226.        $index=0;   
227.        $_ra=array();   
228.        foreach($xls->Worksheet as $worksheet):#循环工作薄   
229.            $index_i=1;   
230.            foreach($worksheet->Table->Row as $cells):#循环行   
231.                if($index_i!==1):   
232.                    foreach($cells as $cell):#循环单元格   
233.                        $_ra[$index][$index_i][]=$is_convert?call_user_func($convert_callback_function,$cell->Data):$cell->Data;   
234.                    endforeach;   
235.                endif;   
236.                $index_i++;   
237.            endforeach;   
238.            $index++;   
239.        endforeach;   
240.        return $_ra;   
241.    }   
242.    /**  
243.     * @desc 设置字符编码  
244.     * @param string $charset 设置导出文件的编码  
245.     */  
246.    public function setCharset($charset="GBK")   
247.    {   
248.        $this->charset = $charset;   
249.    }   
250.  
251.    /**  
252.     * 设置工作薄的列的宽度 array(1=>10,2=>23,3=>23,4=>213,5=>asd) 重复设置该值 将覆盖前一次操作的结果  
253.     * @param string $sheet 工作薄名  
254.     * @param array $array 列数组  
255.     */  
256.    public function setColumnWidth($sheet="sheet1",$array)   
257.    {   
258.        if(!emptyempty($this->_column[$sheet]['style_width'])&&isset($this->_column[$sheet]['style_width'])):   
259.            unset($this->_column[$sheet]['style_width']);   
260.        endif;   
261.        $this->_column[$sheet]['style_width']=$array;   
262.    }   
263.    /**  
264.     * @desc 设置所有工作薄的列宽度  
265.     * @param array $array 列宽度  
266.     */  
267.    public function setAllColumnWidth(array $array)   
268.    {   
269.        $_temp=$this->getAllSheetNames();   
270.        foreach($_temp as $value):   
271.            $this->setColumnWidth($value,$array);   
272.        endforeach;   
273.    }   
274.    /**  
275.     * @desc 设置默认行高  
276.     * @param integer $height  
277.     */  
278.    public function setDefaultRowHeight($height="54")   
279.    {   
280.        $this->defaultHeight=$height;   
281.    }   
282.    /**  
283.     * 设置字符编码转换函数(回调函数)  
284.     * @param string $convert 设置转换函数 默认名称为convert  
285.     */  
286.    public function addConvert($convert="convert")   
287.    {   
288.        $this->convert = $convert;   
289.    }   
290.    /**  
291.     * @desc 内部回调函数,完成字符编码的转化  
292.     * @param unknown_type $str  
293.     */  
294.    protected function convert($str)   
295.    {   
296.        if(function_exists($this->convert)):   
297.            return call_user_func($this->convert,$str);   
298.        else:   
299.            return $str;   
300.        endif;   
301.    }   
302.    /**  
303.     * 获取工作薄个数  
304.     * @param int $sheet 获取工作薄的个数  
305.     * @return integer  
306.     */  
307.    public function getSheets()   
308.    {   
309.        return sizeof($this->_line);   
310.    }   
311.    /**  
312.     * 获取工作薄表格行数  
313.     * @param String $sheet 工作薄名  
314.     * @return integer  
315.     */  
316.    public function getRows($sheet)   
317.    {   
318.        return sizeof($this->_line[$sheet]);   
319.    }   
320.    /**  
321.     * @desc 获取指定工作薄的表头信息  
322.     * @param string $sheet 工作薄名称  
323.     */  
324.    public function getHead($sheet)   
325.    {   
326.        return $this->_heads[$sheet][0];   
327.    }   
328.    /**  
329.     * @desc 设置默认行高度  
330.     * @param integer $defaultHeight 行的默认高度 无默认值  
331.     */  
332.    public function setDefaultHeight($defaultHeight) {   
333.        $this->defaultHeight = $defaultHeight;   
334.    }   
335.    /**  
336.     * @desc 设置默认的列宽度  
337.     * @param integer $defaultWidth 列的默认宽度 无默认值  
338.     */  
339.    public function setDefaultWidth($defaultWidth) {   
340.        $this->defaultWidth = $defaultWidth;   
341.    }   
342.    /**  
343.     * @desc 当前工作薄可用行数  
344.     */  
345.    public function currentSheetsLength()   
346.    {   
347.        return sizeof($this->_line)+1;   
348.    }   
349.    /**  
350.     * @desc 设置默认的居中方式  
351.     * @param string $_align 可选值 Left(left),Center(center),Right(right)  
352.     */  
353.    public function setDefaultAlign($_align)   
354.    {   
355.        $this->_align = ucfirst($_align);   
356.    }   
357.    /**  
358.     * @desc 自动创建工作薄,支持自动分卷技术,该方法与addHead冲突,使用该方法时请勿调用addHead,否则将添加一个空白的工作薄  
359.     * @param array $head 表头  
360.     * @param array $data 数据  
361.     * @param int $pageSize 页面行数 默认60000,excel最大支持65536  
362.     * @param string $defaultName 工作薄名,工作簿不能重名  
363.     */  
364.    public function addPageRow(array $head,array $data,$pageSize=60000,$defaultName="Sheet")   
365.    {   
366.        if(!isset($defaultName)||$defaultName=="Sheet")$defaultName="Sheet".($this->getSheets()+1);   
367.        if(emptyempty(self::$pre_workBook)):   
368.            self::$pre_workBook=$defaultName;   
369.            if(!isset($this->_heads[self::$pre_workBook][0]))   
370.            $this->addHead($head,self::$pre_workBook);   
371.            $this->addRow($data,self::$pre_workBook);   
372.        else:   
373.            if($this->getRows(self::$pre_workBook)>=($pageSize+1)):   
374.                $this->addHead($head,$defaultName);   
375.                $this->addRow($data,$defaultName);   
376.                self::$pre_workBook=$defaultName;   
377.            else:   
378.                $this->addRow($data,self::$pre_workBook);   
379.            endif;   
380.        endif;   
381.    }   
382.    /**  
383.     * @desc 返回所有工作薄名  
384.     * @param null  
385.     */  
386.    public function getAllSheetNames()   
387.    {   
388.        return $this->_sheets;   
389.    }   
390.    /**  
391.     * @desc 设置所有表格标题(分卷) 默认为合并当前工作薄的所有列,并居中显示(粗体) 该方法必须在工作簿存在的情况下调用.  
392.     * @param string $title 标题  
393.     */  
394.    public function setAllTitle($title)   
395.    {   
396.        $_temp=$this->getAllSheetNames();   
397.        foreach($_temp as $value):   
398.            $this->addTitle($title,$value);   
399.        endforeach;   
400.    }   
401.    /**  
402.     * @desc 编码转换函数  
403.     * @param string $str 转换的字符串  
404.     * @param string $source_code 原编码 默认UTF-8  
405.     * @param string $target_code 目标编码 默认GBK  
406.     */  
407.    protected function getConvertString($str,$source_code='UTF-8',$target_code='GBK')   
408.    {   
409.        return !emptyempty($str)&&is_string($str)?iconv($source_code,$target_code,$str):$str;   
410.    }   
411.    /**  
412.     * @desc 打印调试信息  
413.     * @param null  
414.     */  
415.    public function debug($out=true)   
416.    {   
417.        if($out):   
418.            var_dump($this->_line);   
419.        else:   
420.            return $this->_line;   
421.        endif;   
422.    }   
423.    /**  
424.     * @desc 工作薄命名后缀 调用此方法将生成全局唯一工作薄名  
425.     * @param $name 自定义工作薄名  
426.     */  
427.    public function uniqueName($name)   
428.    {   
429.        $size=$this->getSheets();   
430.        if($size==0)return $name;   
431.        else return $name.$size;   
432.    }   
433.    /**设置单位格数据类型,该方法需在填充数据前完成 数据类型参照指定版本的excel  
434.     * @param $_columnType the $_columnType to set array 指定的键值对数组  
435.     */  
436.    public function set_columnType($_columnType)   
437.    {   
438.        $this->_columnType = $_columnType;   
439.    }   
440.}   
441.?>

转载于:https://my.oschina.net/mengdejun/blog/9425

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值