Export.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. /**
  3. * Export.php UTF-8
  4. * 导出类
  5. *
  6. * @date : 2018/5/28 11:39
  7. *
  8. * @license 这不是一个自由软件,未经授权不许任何使用和传播。
  9. * @author : wuyonghong <wyh@huosdk.com>
  10. * @version : HUOSDK 8.0
  11. */
  12. namespace huolib\tool;
  13. use ZipArchive;
  14. class Export {
  15. const MAX_ROWS = 10000; /* 一个文件最多1万行 */
  16. public static function ins() {
  17. return new static();
  18. }
  19. /**
  20. * 因为EXCEL单表只能显示104W数据,同时使用PHPEXCEL容易因为数据量太大而导致占用内存过大,
  21. * 因此,数据的输出用csv文件的格式输出,但是csv文件用EXCEL软件读取同样会存在只能显示104W的情况,
  22. * 所以将数据分割保存在多个csv文件中,并且最后压缩成zip文件提供下载
  23. *
  24. * @param array $head 数据头
  25. * @param array $data 数据
  26. * @param string $path 存储的相对路径
  27. * @param string $file_name 文件名称
  28. * @param string $extend 扩展
  29. * @param bool $is_output 是否直接输出
  30. */
  31. public static function exportCsv($head, $data, $path = '', $file_name = "", $extend = '.csv', $is_output = false) {
  32. if (empty($path)) {
  33. $_root_path = RUNTIME_PATH.'export';
  34. } else {
  35. $_root_path = RUNTIME_PATH.'export'.DS.$path;
  36. }
  37. if (!is_dir($_root_path)) {
  38. @mkdir($_root_path, 0755, true);
  39. }
  40. set_time_limit(0);
  41. if (empty($file_name)) {
  42. $_file_name = date('YmdHi', time()).$extend;
  43. } else {
  44. $_file_name = $file_name.$extend;
  45. }
  46. $_limit = self::MAX_ROWS;
  47. $_cnt = 0;
  48. $_file_path = $_root_path.DS.$_file_name;
  49. $_file_path = iconv('UTF-8', 'GBK', $_file_path);
  50. // 逐行取出数据,不浪费内存
  51. $_fp = fopen($_file_path, 'w'); //生成临时文件
  52. // 将数据通过fputcsv写到文件句柄
  53. if (!empty($head)) {
  54. foreach ($head as $_key => $_val) {
  55. $head[$_key] = iconv('utf-8', 'gbk', $_val);
  56. }
  57. fputcsv($_fp, $head);
  58. }
  59. foreach ($data as $_row) {
  60. $_cnt++;
  61. if ($_limit == $_cnt) {
  62. //刷新一下输出buffer,防止由于数据过多造成问题
  63. ob_flush();
  64. flush();
  65. $_cnt = 0;
  66. }
  67. foreach ($_row as $_key => $_val) {
  68. $_row[$_key] = iconv('utf-8', 'gbk//IGNORE', $_val);
  69. }
  70. fputcsv($_fp, $_row);
  71. }
  72. fclose($_fp); //每生成一个文件关闭
  73. if ($is_output) {
  74. // 输出Excel文件头,可把user.csv换成你要的文件名
  75. header('Content-Type: application/vnd.ms-excel;charset=utf-8');
  76. header('Content-Disposition: attachment;filename="'.$_file_name.'"');
  77. header('Cache-Control: max-age=0');
  78. @readfile($_file_path);//输出文件;
  79. exit;
  80. }
  81. }
  82. /**
  83. * 输出为压缩文件
  84. *
  85. * @param array $file_name_arr 需要压缩的文件名
  86. * @param string $path 存储的相对路径
  87. * @param string $mark 压缩文件名称
  88. */
  89. public static function exportZip($file_name_arr, $path = '', $mark) {
  90. if (empty($file_name_arr)) {
  91. return;
  92. }
  93. if (empty($path)) {
  94. $_root_path = RUNTIME_PATH.'export';
  95. } else {
  96. $_root_path = RUNTIME_PATH.'export'.DS.$path;
  97. }
  98. if (!is_dir($_root_path)) {
  99. @mkdir($_root_path, 0755, true);
  100. }
  101. //进行多个文件压缩
  102. $_zip_class = new ZipArchive();
  103. $_file_name = $mark.".zip";
  104. $_file_path = $_root_path.DS.$_file_name;
  105. $_file_path = iconv('UTF-8', 'GBK', $_file_path);
  106. $_zip_class->open($_file_path, ZipArchive::CREATE); //打开压缩包
  107. foreach ($file_name_arr as $file) {
  108. $_basename = $file;
  109. $file = $_root_path.DS.$file;
  110. $file = iconv('UTF-8', 'GBK', $file);
  111. $_zip_class->addFile($file, $_basename); //向压缩包中添加文件
  112. }
  113. $_zip_class->close(); //关闭压缩包
  114. //输出压缩文件提供下载
  115. header("Cache-Control: max-age=0");
  116. header("Content-Description: File Transfer");
  117. header('Content-disposition: attachment; filename='.$_file_name); // 文件名
  118. header("Content-Type: application/zip"); // zip格式的
  119. header("Content-Transfer-Encoding: binary"); //
  120. header('Content-Length: '.filesize($_file_path)); //
  121. @readfile($_file_path);//输出文件;
  122. @unlink($_file_path); //删除压缩包临时文件
  123. exit;
  124. }
  125. }