php导出CSV抽象类实例

这篇文章主要介绍了php导出CSV抽象类及其用法示例,可实现循环导出功能,从而避免内存不足的问题,需要的朋友可以参考下。

本文实例讲述了php导出CSV抽象类及其应用,分享给大家供大家参考。具体分析如下:

该php导出CSV抽象类,可根据总记录数与每批次记录数,计算总批次,循环导出。避免内存不足的问题。

ExportCSV.class.php类文件如下:

  1. <?php
  2. /** php Export CSV abstract class,根据总记录数与每批次记录数,计算总批次,循环导出。
  3. * Date: 2014-05-16
  4. * Author: fdipzone
  5. * Ver: 1.0
  6. *
  7. * Func:
  8. * public setPageSize 设置每批次导出的记录条数
  9. * public setExportName 设置导出的文件名
  10. * public setSeparator 设置分隔符
  11. * public setDelimiter 设置定界符
  12. * public export 执行导出
  13. * private getPageCount 计算导出总批次
  14. * private setHeader 设置导出文件header
  15. * private formatCSV 将数据格式化为csv格式
  16. * private escape 转义字符串
  17. * abstract getExportTotal 获取总记录条数,抽象方法,需继承类实现
  18. * abstract getExportFields 获取导出的列名,抽象方法,需继承类实现
  19. * abstract getExportData 获取每页记录,抽象方法,需继承类实现
  20. */
  21. abstract class ExportCSV{ // class start
  22. // 定义子类必须要实现的方法
  23. /** 获取总记录条数
  24. * @return int
  25. */
  26. abstract protected function getExportTotal();
  27. /** 获取导出的列名
  28. * @return Array
  29. */
  30. abstract protected function getExportFields();
  31. /** 获取每批次数据
  32. * @param int $offset 偏移量
  33. * @param int $limit 获取的记录条数
  34. * @return Array
  35. */
  36. abstract protected function getExportData($offset, $limit);
  37. // 定义类属性
  38. protected $total = 0; // 总记录数
  39. protected $pagesize = 500; // 每批次导出的记录数
  40. protected $exportName = 'export.csv'; // 导出的文件名
  41. protected $separator = ','; // 设置分隔符
  42. protected $delimiter = '"'; // 设置定界符
  43. /** 设置每次导出的记录条数
  44. * @param int $pagesize 每次导出的记录条数
  45. */
  46. public function setPageSize($pagesize=0){
  47. if(is_numeric($pagesize) && $pagesize>0){
  48. $this->pagesize = $pagesize;
  49. }
  50. }
  51. /** 设置导出的文件名
  52. * @param String $filename 导出的文件名
  53. */
  54. public function setExportName($filename){
  55. if($filename!=''){
  56. $this->exportName = $filename;
  57. }
  58. }
  59. /** 设置分隔符
  60. * @param String $separator 分隔符
  61. */
  62. public function setSeparator($separator){
  63. if($separator!=''){
  64. $this->separator = $separator;
  65. }
  66. }
  67. /** 设置定界符
  68. * @param String $delimiter 定界符
  69. */
  70. public function setDelimiter($delimiter){
  71. if($delimiter!=''){
  72. $this->delimiter = $delimiter;
  73. }
  74. }
  75. /** 导出csv */
  76. public function export(){
  77. // 获取总记录数
  78. $this->total = $this->getExportTotal();
  79. // 没有记录
  80. if(!$this->total){
  81. return false;
  82. }
  83. // 计算导出总批次
  84. $pagecount = $this->getPageCount();
  85. // 获取导出的列名
  86. $fields = $this->getExportFields();
  87. // 设置导出文件header
  88. $this->setHeader();
  89. // 循环导出
  90. for($i=0; $i<$pagecount; $i++){
  91. $exportData = '';
  92. if($i==0){ // 第一条记录前先导出列名
  93. $exportData .= $this->formatCSV($fields);
  94. }
  95. // 设置偏移值
  96. $offset = $i*$this->pagesize;
  97. // 获取每页数据
  98. $data = $this->getExportData($offset, $this->pagesize);
  99. // 将每页数据转换为csv格式
  100. if($data){
  101. foreach($data as $row){
  102. $exportData .= $this->formatCSV($row);
  103. }
  104. }
  105. // 导出数据
  106. echo $exportData;
  107. }
  108. }
  109. /** 计算总批次 */
  110. private function getPageCount(){
  111. $pagecount = (int)(($this->total-1)/$this->pagesize)+1;
  112. return $pagecount;
  113. }
  114. /** 设置导出文件header */
  115. private function setHeader(){
  116. header('content-type:application/x-msexcel');
  117. $ua = $_SERVER['HTTP_USER_AGENT'];
  118. if(preg_match("/MSIE/", $ua)){
  119. header('content-disposition:attachment; filename="'.rawurlencode($this->exportName).'"');
  120. }elseif(preg_match("/Firefox/", $ua)){
  121. header("content-disposition:attachment; filename*=\"utf8''".$this->exportName.'"');
  122. }else{
  123. header('content-disposition:attachment; filename="'.$this->exportName.'"');
  124. }
  125. ob_end_flush();
  126. ob_implicit_flush(true);
  127. }
  128. /** 格式化为csv格式数据
  129. * @param Array $data 要转换为csv格式的数组
  130. */
  131. private function formatCSV($data=array()){
  132. // 对数组每个元素进行转义
  133. $data = array_map(array($this,'escape'), $data);
  134. return $this->delimiter.implode($this->delimiter.$this->separator.$this->delimiter, $data).$this->delimiter."\r\n";
  135. }
  136. /** 转义字符串
  137. * @param String $str
  138. * @return String
  139. */
  140. private function escape($str){
  141. return str_replace($this->delimiter, $this->delimiter.$this->delimiter, $str);
  142. } //www.phpfensi.com
  143. } // class end
  144. ?>

demo示例程序如下:

  1. <?php
  2. // ExportCSV abstract class
  3. require "ExportCSV.class.php";
  4. // 定义继承类
  5. class myexport extends ExportCSV{
  6. // 要导出的数据,实际情况会从db读取
  7. protected $data = array(
  8. array('1','傲雪星枫"','男'),
  9. array('2','傲雪星枫","','男'),
  10. array('3','傲雪星枫","','男'),
  11. array('4',"傲雪星枫\"\"\r\n换行",'男'),
  12. array('5','傲雪星枫,,','男'),
  13. array('6','傲雪星枫"','男'),
  14. array('7','傲雪星枫','男'),
  15. array('8','傲雪星枫','男'),
  16. array('9','傲雪星枫','男'),
  17. array('10','傲雪星枫','男')
  18. );
  19. /* 返回总导出记录数
  20. * @return int
  21. */
  22. protected function getExportTotal(){
  23. return count($this->data);
  24. }
  25. /** 返回导出的列名
  26. * @return Array
  27. */
  28. protected function getExportFields(){
  29. $title = array('id','name','gender');
  30. return $title;
  31. }
  32. /* 返回每批次的记录
  33. * @param int $offset 偏移量
  34. * @param int $limit 获取的记录条数
  35. * @return Array
  36. */
  37. protected function getExportData($offset, $limit){
  38. return array_slice($this->data, $offset, $limit);
  39. }
  40. }
  41. // 导出
  42. $obj = new myexport();
  43. $obj->setPageSize(1);
  44. $obj->setExportName('myexport.csv');
  45. $obj->setSeparator(',');
  46. $obj->setDelimiter('"');
  47. $obj->export();
  48. ?>