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.?>