项目开发中,很多时候要将外部CSV文件导入到数据库中或者将数据导出为CSV文件,那么具体该如何实现呢?本文将使用PHP并结合mysql,实现了CSV格式数据的导入和导出功能。
常用函数:
fopen() 函数打开文件或者 URL fgetcsv() 函数从文件指针中读入一行并解析 CSV 字段。 与 fgets() 类似,不同的是 fgetcsv() 解析读入的行并找出 CSV 格式的字段,然后返回一个包含这些字段的数组。 fgetcsv() 出错时返回 FALSE,包括碰到文件结束时。 fputcsv() 函数将行格式化为 CSV 并写入一个打开的文件。 该函数返回写入字符串的长度。若出错,则返回 false。。 mb_convert_encoding ( string $str , string $to_encoding [, mixed $from_encoding = mb_internal_encoding() ]) 转换字符的编码 iconv ( string $in_charset , string $out_charset , string $str ) 函数返回字符串
我们先准备mysql数据表,假设项目中有一张记录学生信息的表student,并有id,name,sex,age分别记录学生的姓名、性别、年龄等信息。
DROP TABLE IF EXISTS `ks_student`; CREATE TABLE `ks_student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL, `sex` char(2) DEFAULT NULL, `age` tinyint(3) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我们还需要一个html交互页面,放置导入表单和导出按钮。
<form id="uploadForm" action="__URL__/action?act=import" method="post" enctype="multipart/form-data">
<input type="text" name="username" class="username"> <br/>
<p>请选择要导入的CSV文件:<br/>
<input type="file" name="file" class="file">
<input type="hidden" name="act" class="act" value="import">
<input type="submit" class="btn import" value="导入CSV">
</form>
<a href="__URL__/action?act=export">
<button type="submit" class="btn btn-default record">导出CSV</button>
</a>
<div class="content" style="width:300px;height:auto;"></div>
<script>
$(function(){
$('#uploadForm').ajaxForm({
dataType: 'json',
success: processJson
});
function processJson(re){
if(re.status == '1'){
var re = re.info;
for(var i=0; i < re.length;i++){
var html="";
html +="<div>";
html +='<span class="name" style="padding-right: 30px;">'+re[i].name+'</span>';
html +='<span class="sex" style="padding-right: 30px;">'+re[i].sex+'</span>';
html +='<span class="age">'+re[i].age+'</span>';
html +="</div>";
$(html).appendTo(".content");
}
} else{
alert(re.info);
}
}
$(".export").click(function(){
var url ="__URL__/action?act=export";
window.location.href=url;
});
});
</script>选择好本地csv文件后,点击导入,提交到do.php?action=import处理,而点击导出按钮则请求地址do.php?action=export进行数据导出处理。
使用tp3.2框架具体处理
1.配置数据库
return array( //'配置项'=>'配置值' /* 数据库设置 */ 'DB_TYPE' => 'mysql', // 数据库类型 'DB_HOST' => 'localhost', // 服务器地址 'DB_NAME' => 'user', // 数据库名 'DB_USER' => 'root', // 用户名 'DB_PWD' => '', // 密码 'DB_PORT' => 3306, // 端口 'DB_PREFIX' => 'ks_', // 数据库表前缀 'DB_CHARSET'=> 'utf8', // 字符集 'DB_DEBUG' => TRUE, // 数据库调试模式 开启后可以记录SQL日志 3.2.3新增 'SHOW_PAGE_TRACE' =>true, // 显示页面Trace信息 );
2.根据get过来的参数,分别处理导入和导出过程,php结构如下:
$action = $_GET['action'];
if ($action == 'import') { //导入CSV
//导入处理
} elseif ($action=='export') { //导出CSV
//导出处理
}注意php自带的fgetcsv函数可以轻松处理csv,使用该函数可以从文件指针中读入一行并解析CSV字段。下面的函数将csv文件字段解析并以数组的形式返回。
function input_csv($handle) {
$out = array ();
$n = 0;
while ($data = fgetcsv($handle, 10000)) {
$num = count($data);
for ($i = 0; $i < $num; $i++) {
$out[$n][$i] = $data[$i];
}
$n++;
}
return $out;
}导入CSV处理流程:校验csv文件合法性(本文忽略)->打开读入并解析csv文件中的字段->循环获取各字段值->批量添加到数据表中->完成。
导出CSV处理流程:读取学生信息表->循环记录构建逗号分隔的字段信息->设置header信息->导出文件(下载)到本地。
<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function index(){
$this->display();
}
/*
csv文件是由逗号分割符组成的纯文本文件,你可以用excel打开,效果跟xls表个一样。
导出CSV处理流程:读取学生信息表->循环记录构建逗号分隔的字段信息->设置header信息->导出文件(下载)到本地
*/
//导入导出csv
public function action(){
header('Content-type:text/html;charset=utf8');
$action = I("act");
if ($action == 'import'){ //导入CSV
$username = I("username");
$filename = $_FILES['file']['tmp_name'];
if(empty($filename)){
echo '请选择要导入的CSV文件!'; exit;
}
$handle = fopen($filename, 'r');
$result = $this->input_csv($handle); //解析csv
$len_result = count($result);
if($len_result==0){
echo '没有任何数据!';exit;
}
$data_values = '';
for($i = 1; $i < $len_result; $i++){ //循环获取各字段值
$name = iconv('gb2312', 'utf-8', $result[$i][0]); //中文转码
$sex = iconv('gb2312', 'utf-8', $result[$i][1]);
//$name = mb_convert_encoding($result[$i][0], "GBK", "UTF-8");
//$sex = mb_convert_encoding($result[$i][1], "GBK", "UTF-8");
$age = $result[$i][2];
$data_values .= "('$name','$sex','$age'),";
}
$data_values = rtrim($data_values,',');
//$data_values = substr($data_values,0,-1); //去掉最后一个逗号
fclose($handle); //关闭指针
$sql = "insert into ks_student (name,sex,age) values $data_values";//批量插入数据表中
$res = M()->execute($sql);
if($res){
$xdata['status'] = '1';
$data = M("Student")->order("id desc")->select();
$xdata['info'] = $data;
}else{
$xdata['status'] = '0';
$xdata['info'] = '导入失败!';
}
echo json_encode($xdata);exit;
}elseif($action=='export'){ //导出CSV
//1、title
$arrtitle = array("name"=>"姓名","sex"=>"性别","age"=>"年龄");
$str = "";
foreach($arrtitle as $value){
$str .= $value .",";
}
$str = rtrim($str,',')."\n";
//2、内容
$result = M("Student")->select();
$content = '';
foreach($result as $key=>$value){
foreach($arrtitle as $k=>$v){
$content .= $value[$k] .",";
}
$content = rtrim($content,",") . "\n";
}
$type = 2;
$filename = date('Y-m-d').'.csv'; //设置文件名
$string = iconv('utf-8','gb2312',$str.$content); //中文转码
//$string = mb_convert_encoding($str.$content, "GBK", "UTF-8");
if($type == 1){
file_put_contents($filename, $string);exit;
}else{ //从浏览器输出
$this->export_csv($filename,$string);
}
/**简单导出方式**********************************************
//1、title
$str = "姓名,性别,年龄\n";
$str = iconv('utf-8','gb2312',$str);
//$str = mb_convert_encoding($str, "GBK", "UTF-8");
//2、内容
$result = M("Student")->select();
foreach($result as $key=>$value){
$name = iconv('utf-8','gb2312',$value['name']); //中文转码
//$name = mb_convert_encoding($value['name'], "GBK", "UTF-8");
$sex = iconv('utf-8','gb2312',$value['sex']);
//$sex = mb_convert_encoding($value['sex'], "GBK", "UTF-8");
$sex = $value['age'];
$str .= $name.",".$sex.",".$sex."\n"; //用引文逗号分开
}
$filename = date('Y-m-d').'.csv'; //设置文件名
file_put_contents($filename, $str);
**************************************************************/
}else{
$this->error("错误操作!");
}
}
/*注意php自带的fgetcsv函数可以轻松处理csv,
使用该函数可以从文件指针中读入一行并解析CSV字段。
下面的函数将csv文件字段解析并以数组的形式返回*/
public function input_csv($handle){
$out = array ();
$n = 0;
while ($data = fgetcsv($handle, 10000)){
$num = count($data);
for ($i = 0; $i < $num; $i++){
$out[$n][$i] = $data[$i];
}
$n++;
}
return $out;
}
//输出到浏览器
public function export_csv($filename,$data){
header("Content-type:text/csv;");
header("Content-Disposition:attachment;filename=" . $filename);
header('Cache-Control:must-revalidate,post-check=0,pre-check=0');
header('Expires:0');
header('Pragma:public');
echo $data;exit;
}
}注意导入和导出的过程中,因为我们使用的是统一UTF-8编码,遇到中文字符一定要记得转码,否则可能会出现中文乱码的情况。
本文为崔凯原创文章,转载无需和我联系,但请注明来自冷暖自知一抹茶ckhttp://www.cksite.cn