excel.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. /**
  3. * 生成Excel文件类
  4. *
  5. * @package
  6. */
  7. defined('InShopNC') or exit('Access Invalid!');
  8. class Excel{
  9. /**
  10. * excel文档头(返回的行)
  11. *
  12. * 依照excel xml规范。
  13. * @access private
  14. * @var string
  15. */
  16. private $header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?\>
  17. <Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"
  18. xmlns:x=\"urn:schemas-microsoft-com:office:excel\"
  19. xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"
  20. xmlns:html=\"http://www.w3.org/TR/REC-html40\">";
  21. /**
  22. * excel页脚
  23. * 依照excel xml规范。
  24. *
  25. * @access private
  26. * @var string
  27. */
  28. private $footer = "</Workbook>";
  29. /**
  30. * 文档行(行数组中)
  31. *
  32. * @access private
  33. * @var array
  34. */
  35. private $lines = array ();
  36. /**
  37. * 工作表(数组)
  38. *
  39. * @access private
  40. * @var array
  41. */
  42. private $worksheets = array ();
  43. /**
  44. * 单元格样式
  45. * @access private
  46. * @var string
  47. */
  48. private $cellstyle = array();
  49. /**
  50. * 默认单元格数据格式
  51. * @access private
  52. * @var string
  53. */
  54. private $default_cellformat = "String";
  55. public function __construct(){
  56. //设置默认样式
  57. $this->cellstyle['Default'] = '<Style ss:ID="Default" ss:Name="Normal">
  58. <Alignment ss:Vertical="Center"/>
  59. <Borders/>
  60. <Font ss:FontName="宋体" x:CharSet="134" ss:Size="11" ss:Color="#000000"/>
  61. <Interior/>
  62. <NumberFormat/>
  63. <Protection/>
  64. </Style>';
  65. }
  66. /**
  67. * 添加单行数据
  68. *
  69. * @access private
  70. * @param array 1维数组
  71. * @todo 行创建
  72. */
  73. private function addRow ($array)
  74. {
  75. //初始化单元格
  76. $cells = "";
  77. //构建单元格
  78. foreach ($array as $k => $v){
  79. $style_str = '';
  80. if(!empty($v['styleid'])){
  81. $style_str = 'ss:StyleID="'.$v['styleid'].'"';
  82. }
  83. $format_str = $this->default_cellformat;
  84. if(!empty($v['format'])){
  85. $format_str = $v['format'];
  86. }
  87. $cells .= "<Cell {$style_str} ><Data ss:Type=\"{$format_str}\">{$v['data']}</Data></Cell>\n";
  88. }
  89. //构建行数据
  90. $this->lines[] = "<Row>\n" . $cells . "</Row>\n";
  91. }
  92. /**
  93. * 添加多行数据
  94. * @access public
  95. * @param array 2维数组
  96. * @todo 构造多行
  97. */
  98. public function addArray ($array)
  99. {
  100. $this->lines = array();
  101. //构建行数据
  102. foreach ((array)$array as $k => $v){
  103. $this->addRow ($v);
  104. }
  105. }
  106. /**
  107. * 添加工作表
  108. * @access public
  109. * @param string $sheettitle 工作表名
  110. * @todo 构造工作表XML
  111. */
  112. public function addWorksheet($sheettitle)
  113. {
  114. //剔除特殊字符
  115. $sheettitle = preg_replace ("/[\\\|:|\/|\?|\*|\[|\]]/", "", $sheettitle);
  116. //现在,将其减少到允许的长度
  117. //$sheettitle = substr ($sheettitle, 0, 50);
  118. $this->worksheets[] = "\n<Worksheet ss:Name=\"$sheettitle\">\n<Table ss:DefaultRowHeight=\"20\">\n".
  119. "<Column ss:Index=\"1\" ss:AutoFitWidth=\"0\"/>\n".
  120. implode ("\n", $this->lines).
  121. "</Table>\n</Worksheet>\n";
  122. }
  123. /**
  124. * 设置单元格样式
  125. *
  126. * @access public
  127. * @param array 样式数组例如: array('id'=>'s_title','Font'=>array('FontName'=>'宋体','Size'=>'12','Bold'=>'1'));
  128. * 当id为Default时,为表格的默认样式
  129. */
  130. public function setStyle ($style_arr){
  131. if(empty($style_arr)){
  132. return false;
  133. }
  134. $id = $style_arr['id'];
  135. unset($style_arr['id']);
  136. $style_str = "<Style ss:ID=\"$id\">";
  137. foreach($style_arr as $k=>$v){
  138. $tmp = '';
  139. foreach((array)$v as $k_item=>$v_item){
  140. $tmp .= (" ss:$k_item=\"$v_item\"");
  141. }
  142. $style_str .= "<$k ".$tmp.'/>';
  143. }
  144. $this->cellstyle[$id] = $style_str.'</Style>';
  145. }
  146. /**
  147. * 设置默认单元格格式
  148. *
  149. * @access public
  150. * @param string
  151. */
  152. public function setDefaultFormat ($format_str){
  153. if(empty($style_arr)){
  154. return false;
  155. }
  156. $this->default_cellformat = $format_str;
  157. }
  158. /**
  159. * 生成excel文件
  160. * 最后生成excel文件,并使用header()函数来将它交付给浏览器。
  161. * @access public
  162. * @param string $filename 文件名称
  163. */
  164. public function generateXML ($filename)
  165. {
  166. $encoded_filename = urlencode($filename);
  167. $encoded_filename = str_replace("+", "%20", $encoded_filename);
  168. //头
  169. $ua = $_SERVER["HTTP_USER_AGENT"];
  170. header("Content-Type: application/vnd.ms-excel");
  171. if(preg_match("/MSIE/", $ua)){
  172. header('Content-Disposition: attachment; filename="'.$encoded_filename.'.xls"');
  173. }else if(preg_match("/Firefox/", $ua)){
  174. header('Content-Disposition: attachment; filename*="utf8\'\''.$filename.'.xls"');
  175. }else{
  176. header('Content-Disposition: attachment; filename="'.$filename.'.xls"');
  177. }
  178. header('Cache-Control: max-age=0');
  179. echo stripslashes ($this->header);
  180. //样式
  181. echo "\n<Styles>";
  182. foreach((array)$this->cellstyle as $k=>$v){
  183. echo "\n".$v;
  184. }
  185. echo "\n</Styles>";
  186. //工作表
  187. echo implode ("\n", $this->worksheets);
  188. echo $this->footer;
  189. }
  190. /**
  191. * 转码函数
  192. *
  193. * @param mixed $content
  194. * @param string $from
  195. * @param string $to
  196. * @return mixed
  197. */
  198. public function charset($content, $from='gbk', $to='utf-8') {
  199. $from = strtoupper($from) == 'UTF8' ? 'utf-8' : $from;
  200. $to = strtoupper($to) == 'UTF8' ? 'utf-8' : $to;
  201. if (strtoupper($from) === strtoupper($to) || empty($content)) {
  202. //如果编码相同则不转换
  203. return $content;
  204. }
  205. if (function_exists('mb_convert_encoding')) {
  206. if (is_array($content)){
  207. $content = var_export($content, true);
  208. $content = mb_convert_encoding($content, $to, $from);
  209. eval("\$content = $content;");return $content;
  210. }else {
  211. return mb_convert_encoding($content, $to, $from);
  212. }
  213. } elseif (function_exists('iconv')) {
  214. if (is_array($content)){
  215. $content = var_export($content, true);
  216. $content = iconv($from, $to, $content);
  217. eval("\$content = $content;");return $content;
  218. }else {
  219. return iconv($from,$to,$content);
  220. }
  221. } else {
  222. return $content;
  223. }
  224. }
  225. }
  226. ?>