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