PHP自封装CSV文件导入导出类,不依赖其他插件,代码简短简洁,引用简单方便,性能稳定,兼容性强,喜欢的给个赞!
PHP自封装CSV文件导入导出类,不依赖其他插件,代码简短简洁,引用简单方便,性能稳定,兼容性强,喜欢的给个赞!
用PHP语言在做管理系统的时候,有时需要将数据库里边的内容导出Execl表格,或者有时将Execl表格数据导入数据库中,网上有很多现成的插件也有网友自己写的,这里我整理了一份,自己封装的,使用简单方便,示例如下。
csv测试文件内容如下:
用浏览器打开demo.html测试页面如下:
demo.html源码:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>PHP自封装CSV文件导入导出类不依赖其他插件</title>
</head>
<body>
<form action="test.php?go=1" method="post" enctype="multipart/form-data">
<p>请选择要导入的CSV文件:</p>
<input type="file" name="file_execl">
<input type="submit" class="btn" value="点击上传解析CSV">
</form>
<br><hr><br>
<a href="test.php?go=2">点击测试导出CSV</a>
</body>
</html>
test.php文件:
<?php
include 'PHPCsvArr.php';
// 导入示例:
if(isset($_GET['go']) && $_GET['go'] == 1){
$fileName = 'file_execl'; // input file 控件名
$csv = new PHPCsvArr();
$result = $csv->de_csv($fileName); // 解析csv文件内容转数组
print_r($result);exit; // 打印结果
}
// 导出示例:
if(isset($_GET['go']) && $_GET['go'] == 2){
// 模拟个从数据库读取的二维数组数据
$list = array(
array('code'=>'123456781', 'name'=>'PHP - 越加网','content'=>'超文本预处理器'),
array('code'=>'123456782', 'name'=>'HTML - 越加网','content'=>'超文本标记语言'),
array('code'=>'123456783', 'name'=>'CSS - 越加网','content'=>'层叠样式表'),
);
$fileTitle = '产品列表'; // 导出文件的名称
$data = array('code'=>'编码', 'name'=>'编程', 'content'=>'介绍'); // 导出文件的数据标头
$e = array('code'); // 可以不定义或者为空,指定字段值屏蔽科学计数法
$csv = new PHPCsvArr(); // 实例化类
$csv->export($list, $fileTitle, $data, $e);
}
?>
导入csv文件时打印出内容示例:
Array
(
[code] => 1
[msg] => Success
[data] => Array
(
[0] => Array
(
[A] => 编号
[B] => 编程
[C] => 简介
)
[1] => Array
(
[A] => 1001
[B] => PHP
[C] => 超文本预处理器
)
[2] => Array
(
[A] => 1002
[B] => HTML
[C] => 超文本标记语言
)
[3] => Array
(
[A] => 1003
[B] => CSS
[C] => 层叠样式表
)
)
)
导出csv文件时的内容示例:
PHPCsvArr.php类文件源码:
<?php
/**
* @fun: decode csv
* @author: ZHL
* @date: 2020-5-12
* @version: V 1.2
* @desc: csv文件导入导出操作
*/
class PHPCsvArr{
/**
* @fun: CSV文件导入解析成数组
* @author: ZHL
* @date: 2018-3-8
* @param string $fileName 传入控件名
* @return array
*/
public function de_csv($fileName = 'file'){
$file = $_FILES[$fileName]['tmp_name'];
$hint = array('code'=>'0','msg'=>'Error','data'=>array());
if(!empty($file)){
if(is_array($file)){
foreach($file as $v){
$data = $this->csv_arr($v);
if(!empty($data)){
$hint['data'] = array_merge($hint['data'],$data);
}
}
}else{
$hint['data'] = $this->csv_arr($file);
}
$hint['code'] = 1;
$hint['msg'] = 'Success';
}else{
$hint['code'] = 2;
$hint['msg'] = 'Please select the CSV';
}
return $hint;
}
// 打开csv解析数据转数组
private function csv_arr($file = ''){
$data = array();
$handle = fopen($file, 'r');
$res = $this->input_csv($handle);
if(!empty($res['data'][0][0])){
$td = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM','AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ',
'BA','BB','BC','BD','BE','BF','BG','BH','BI','BJ','BK','BL','BM','BN','BO','BP','BQ','BR','BS','BT','BU','BV','BW','BX','BY','BZ',
'CA','CB','CC','CD','CE','CF','CG','CH','CI','CJ','CK','CL','CM','CN','CO','CP','CQ','CR','CS','CT','CU','CV','CW','CX','CY','CZ',
'DA','DB','DC','DD','DE','DF','DG','DH','DI','DJ','DK','DL','DM','DN','DO','DP','DQ','DR','DS','DT','DU','DV','DW','DX','DY','DZ');
for($i = 0; $i < $res['tr']; $i++) {
for($j = 0; $j < $res['td']; $j++) {
$data[$i][$td[$j]] = $this->convert_str($res['data'][$i][$j]);
}
}
fclose($handle); //关闭指针
}
return $data;
}
// 解析 CSV
private function input_csv($handle){
$n = 0;
$td = 0;
$out = array();
setlocale(LC_ALL, 'zh_CN');
while ($data = fgetcsv($handle, 10000)) {
if(!$n){
$td = count($data);
}
for($i = 0; $i < $td; $i++) {
$out[$n][$i] = $data[$i];
}
$n++;
}
return array('tr'=>$n, 'td'=>$td, 'data'=>$out);
}
// 已知编码 - GB2312转UTF-8
protected function iconv_str($str){
return @iconv('GB2312','UTF-8//TRANSLIT//IGNORE',$str);
}
// 未知编码 - 转UTF-8
protected function convert_str($str){
$encode_arr=array('UTF-8','ASCII','GBK','GB2312','BIG5','JIS','eucjp-win','sjis-win','EUC-JP');
$encode = @mb_detect_encoding($str, $encode_arr);
return @mb_convert_encoding($str,"UTF-8",$encode);
}
/**
* @fun: 数组集导出CSV文件
* @author: ZHL
* @date: 2020-05-12
* @param array $list 数据集(二维数组),
* @param string $title 导出文件名(可为空),
* @param array $data 导出文件列名(一维数组,键名为sql字段名(orcale大写),值为execl列名/别称),
* @param array $e 屏蔽科学计数法(sql字段名,存在即屏蔽)
* @param bool $hiddenNo 是否隐藏
*/
public function export($list, $title='', $data, $e=array(),$hiddenNo = false, $maxLimitFlag = true){
if(empty($list) || empty($data)){
echo '<script type="text/javascript">alert("没有找到数据");history.go(-1);</script>';exit;
}
if($maxLimitFlag && count($list)>5000){
echo '<script type="text/javascript">alert("数据已超出5000条记录!禁止导出");history.go(-1);</script>';exit;
}
$title = $title ? $title : date('YmdHis');
$filename = $title.".csv";
$heads = array_values($data);
if(!$hiddenNo){
array_unshift($heads, '编号');
}
foreach ($heads as $k => $v){
$heads[$k] = iconv('utf-8', 'gbk', $v); //转utf-8
}
ob_end_clean(); // 清空(擦除)缓冲区并关闭输出缓冲
header("Content-type:text/csv"); //定义输出格式
header("Content-type:application/vnd.ms-excel");
header("Content-Disposition:attachment;filename=".$filename);
header('Cache-Control:must-revalidate,post-check=0,pre-check=0,max-age=0');
header('Expires:0');
header('Pragma:public');
//从数据库中获取数据,为了节省内存,不要把数据一次性读到内存,从句柄中一行一行读即可
$fp = fopen('php://output', 'a'); // 表示直接输出到浏览器
fputcsv($fp, $heads); //将数据通过fputcsv写到文件句柄
$cnt = 0; //计数器
$limit = 1000; //每隔$limit行,刷新输出buffer,不要太大,也不要太小
//逐行取出数据,不浪费内存
foreach($list as $key=>$value){
$cnt++;
//刷新一下输出buffer,防止由于数据过多造成问题
if($limit == $cnt){
ob_flush(); // 把数据从PHP的缓冲(buffer)中释放出来。
flush(); // 把不在缓冲(buffer)中的或者说是被释放出来的数据发送到浏览器。
$cnt = 0;
}
$dataRow = array();
$titleKeys = array_keys($data);
foreach($titleKeys as $k=>$v){
if(in_array($v, $e)){
$dataRow[$k] = isset($value[$v]) ? $value[$v]."\t" : '';
}else{
$dataRow[$k] = isset($value[$v]) ? $value[$v] : '';
}
}
if(!$hiddenNo){
array_unshift($dataRow, ($key+1));
}
$row = array();
foreach($dataRow as $j => $v){
$row[$j] = @iconv('utf-8', 'gbk//IGNORE', $v);
}
fputcsv($fp, $row);
}
}
}
完整示例源代码下载:
链接:https://pan.baidu.com/s/1obDHTa8MWRp1opaOu03JdQ
提取码:zjh7