1 <?php
2
3 /**
4 * CSV 文件读写类
5 *
6 * 示例:
7
8 $header = array('name' => '名字', 'age' =>'年龄', 'idcard' => '身份证号');
9
10 $data = array(
11 array('age' => 12, 'name' => '李四', 'idcard' => '42088751564616131312'),
12 (object) array('idcard' => '72888751564616131312', 'age' => 17, 'name' => '张三'),
13 );
14
15 Csv::instance()->open('e:/abc1.csv', true)->header($heaer)->create($data)->close();
16 Csv::instance()->open()->header($header)->create($data)->download('用户数据.csv');
17
18 */
19
20 class Csv {
21
22 public $header = array();
23
24 public $fp = '';
25
26 public static function instance(){
27
28 return new static();
29 }
30
31 /**
32 * 打开/创建文件
33 * @param string $file
34 * @param string $mode
35 * @return $this
36 */
37 public function open($file = '', $mode = 'a'){
38
39 if(empty($file)){
40
41 $this->fp = tmpfile();
42 }else{
43 if($mode === true) $mode = 'w+';
44 $this->fp = fopen(iconv('UTF-8', 'GBK', $file), $mode);
45 }
46
47 return $this;
48
49 }
50
51
52 /**
53 * 写入表头
54 * @param $value
55 * @return $this
56 */
57 public function header($value){
58
59 $this->header = is_array($value)? $value : (array) $value;
60 fputcsv($this->fp, array_values($this->header));
61
62 return $this;
63 }
64
65
66 /**
67 * 写入一行
68 * @param $data
69 * @return $this
70 */
71 public function write($data){
72
73 if(is_string($data)){
74 $data = json_decode($data, true);
75 }else if(!is_array($data)){
76 $data = json_decode(json_encode($data), true);
77 }
78
79 if(empty($data)) return $this;
80
81 if($this->header){
82 $column = array();
83 foreach($this->header as $key => $value){
84 $column[$key] = isset($data[$key])? $data[$key] : 'NULL';
85 }
86 $data = &$column;
87 }
88
89 foreach($data as $key => &$value){
90 if(is_numeric($value) && strlen($value) > 10){
91 $value .= "\t";
92 }else if(!is_scalar($value)){
93 $value = json_encode($value, JSON_UNESCAPED_UNICODE);
94 }
95
96 }
97
98 fputcsv($this->fp, $data);
99
100 return $this;
101 }
102
103 /**
104 * 读取一行
105 * @param int $length
106 * @param string $delimiter
107 * @param string $enclosure
108 * @param string $escape
109 * @return array|false|null
110 */
111 public function read($length = 0, $delimiter = ',', $enclosure = '"', $escape = '\\'){
112
113 return fgetcsv($this->fp, $length, $delimiter, $enclosure, $escape);
114 }
115
116
117 /**
118 * 获取文件内容
119 * @param null $callback
120 * @param int $start
121 * @param int $length
122 * @return array
123 */
124 public function content($callback = null, $start = 1, $length = 0){
125
126 if($start > 1){
127 for($start; $start > 1; $start--){
128 $this->read(1);
129 }
130 }
131
132 $data = array();
133 $key = 0;
134 while(($row = $this->read()) !== false){
135
136 if($length < 0) break;
137 if($length > 0) $length--;
138
139 if(is_callable($callback)){
140 $row = $callback($row);
141 if($row === null) continue;
142 }
143 $data[$key] = $row;
144 $key++;
145
146 }
147
148 return $data;
149 }
150
151
152 /**
153 * 下载
154 * @param $file
155 */
156 public function download($file){
157
158 $file = iconv('UTF-8', 'GBK', $file);
159 header('Content-Type:application/application/octet-stream');
160 header("Content-Disposition:attachment;filename=$file");
161
162 fseek($this->fp, 0);
163 echo stream_get_contents($this->fp);
164
165 $this->close();
166
167 }
168
169
170 /**
171 * 快速写入文件
172 * @param $data
173 * @return $this
174 */
175 public function create($data){
176
177 if(is_string($data)) $data = json_decode($data, true);
178 foreach($data as $row){
179 $this->write($row);
180 }
181
182 return $this;
183
184 }
185
186
187 public function close(){
188
189 fclose($this->fp);
190 }
191
192
193 }