php导入csv文件碰到乱码问题的解决方法


问题一解决: 在windows上写代码的时候测试发生了乱码问题

方法一:函数mb_convert_encoding();作如下设置 $str = mb_convert_encoding($str, "UTF-8", "GBK");然后就可以了。

方法二:函数iconv();作如下设置iconv(‘GBK',”UTF-8//TRANSLIT//IGNORE”,$str);

这两个函数来解决在windows上面发生乱码的问题。 

 

问题二解决: 提交到linux系统上的时候又发生了乱码

php读取csv文件,在linux上出现中文读取不到的情况,解决办法 
添加了一行代码setlocale(LC_ALL, 'zh_CN');

PHP setlocale() 函数解释 

setlocale() 函数设置地区信息(地域信息)。 
地区信息是针对一个地理区域的语言、货币、时间以及其他信息。该函数返回当前的地区设置,若失败则返回 false
以下是在资料上收集常用的地区标识: 

zh_CN GB2312 
en_US.UTF-8 UTF-8 
zh_TW BIG5 
zh_HK BIG5-HKSCS 
zh_TW.EUC-TW EUC-TW 
zh_TW.UTF-8 UTF-8 
zh_HK.UTF-8 UTF-8 
zh_CN.GBK GBK 
例如、 
utf-8: setlocale(LC_ALL, ‘en_US.UTF-8′); 
简体:setlocale(LC_ALL, ‘zh_CN'); 

 

fgetcsv()函数对区域设置是敏感的。比如说 LANG 设为 en_US.UTF-8 的话,单字节编码的文件就会出现读取错误,所以我们需要对其进行区域性的设置。特分享给大家。 

$csvContent="csvzero,csvone,csvtwo,csvthree,csvfour,csvfive"; 
header("Content-Type: application/vnd.ms-excel; charset=GB2312"); 
header("Pragma: public"); 
header("Expires: 0"); 
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
header("Content-Type: application/force-download"); 
header("Content-Type: application/octet-stream"); 
header("Content-Type: application/download"); 
header("Content-Disposition: attachment;filename=CSV数据.csv "); 
header("Content-Transfer-Encoding: binary "); 
$csvContent = iconv("utf-8","gb2312",$csvContent); 
echo $csvContent; 
exit; 

 

 

下面就再来具体看看php导入csv文件的代码: 

mb_detect_encoding()检测到的字符编码,或者无法检测指定字符串的编码时返回FALSE。 

fgetcsv() 函数从文件指针中读入一行并解析 CSV 字段。

与fgets() 类似,不同的是 fgetcsv() 解析读入的行并找出 CSV 格式的字段,然后返回一个包含这些字段的数组。

fgetcsv() 出错时返回 FALSE,包括碰到文件结束时。 

注释:从 PHP 4.3.5 起,fgetcsv() 的操作是二进制安全的。 
注释:CSV 文件中的空行将被返回为一个包含有单个 null 字段的数组,不会被当成错误。 
注释:该函数对区域设置是敏感的。比如说 LANG 设为 en_US.UTF-8 的话,单字节编码的文件就会出现读取错误。 
注释:如果碰到 PHP 在读取文件时不能识别 Macintosh 文件的行结束符,可以激活 auto_detect_line_endings 运行时配置选项。 
  1 setlocale(LC_ALL, 'zh_CN'); //设置地区信息(地域信息) 
  2 $file = $_FILES['files']; 
  3 $file_type = substr(strstr($file['name'],'.'),1); 
  4 if ($file_type != 'csv'){ 
  5   echo "<script type=\"text/javascript\">alert(\"文件格式错误,请重新上传!\"); </script>"; 
  6   exit; 
  7 }
8 $handle = fopen($file['tmp_name'],"r"); 9 $file_encoding = mb_detect_encoding($handle); 10 if ($file_encoding != 'ASCII'){ 11   echo "<script type=\"text/javascript\">alert(\"文件编码错误,请重新上传!\"); </script>"; 12   exit; 13 }
14 $row = 0; 15 $str=""; 16 $sy="";
17 while ($data = fgetcsv($handle,1000,',')){ 18   $row++; 19   if ($row == 0) 20     continue; 21   $num = count($data); 22   for ($i=0; $i<$num; $i++){ 23     $str = (string)$data[$i].'|'; 24     $str = mb_convert_encoding($str, "UTF-8", "GBK"); //已知源码为GBK,转换为utf-8 25     $sy .= $str; //我这里做的比较复杂,是用'|'将csv文件里面的内容用'|'全部拼起来,因为我导入的是商品信息,需要根据用户需 26     //要导入的数据去定义哪些数据是需要导入的。 27   } 28 } 29 if ($sy) { $sy = rtrim($sy, '|'); } 30 $arr = explode('|',$sy); 31 $key = array_slice($arr,0,$num); //这个数组就是csv文件里面标题,就是商品id,标题,卖点等等的数据 32 $skey = array(); 33 $length = array(); 34 $co = count($arr); 35 $p = $co/$num; //求出要取出的数据的长度 36 for($j=0;$j<$p;$j++){ 37  $offset=($j-1)*$num; //偏移量,就像分页一样,我这里根据偏移量取出的一个数组就是一个商品的信息。 38  if($j==0){ 39    $length[] = array_slice($arr,0,$num); 40  }else{ 41    $length[] = array_slice($arr,$num+$offset,$num);//取出有哪些字段和商品 42  } 43 } 44 $arrtitle = array(); 45 $arrfileds = array(); 46 $arrtagname = DB::select('字段标识', '字段名称')->from('字段表')->fetch_all(); 47 foreach ($arrtagname as $value) { 48   $arrfileds[$value['fileds_tags']] = $value['fileds_name']; 49 } 50 foreach ($fileds as $v) 51 { 52   $temarr= explode('-', $v); 53   if (isset($temarr[0]) && !empty($temarr[0])) { 54     if (isset($temarr[1]) && !empty($temarr[1])) { 55       if ($temarr[1] == 'wenben') { 56         $arrtitle[] = $arrfileds[$temarr[0]].'文本'; 57       } 58     } else { 59       if ($temarr[0] != 'pic') { //是取出字段是图片就给去掉 60         $arrtitle[] = $arrfileds[$temarr[0]]; 61       } 62     } 63   } 65 } 66 67 $skey = array(); 68 $order = array(); 69 $order[] = 'act_tag'; 70 $order[] = 'channel_tag'; 71 $order[] = 'created_time'; 72 $order[] = 'orderby'; 73 $rows =''; 74 $f = $co/$num;//求出有多少件商品 75 for($p=0;$p<count($arrtitle);$p++){ 76   //这里就是根据自己的需求查出自己需要的数据,通过用户需要的商品字段标识查出表里相对应的英文标识。 77   $skey[]= DB::select('字段标识')->from('字段表')->where('字段名称', '=', $arrtitle[$p])->fetch_row(); 78   $rows .= $skey[$p]['字段标识'].'|'; 79 } 80 if($rows){ $rows = rtrim($rows,'|'); } 81 if(!empty($rows)){ $exrows = explode('|',$rows); }else{ $exrows = array(); } 82 $skeys = array_merge($order,$exrows); 83 $count1 = count($skeys); //字段的个数 84 if(!empty($length)){ 85 for($x=1;$x<$f;$x++){ //求出有多少件商品就的循环多少次 86   $orders = array(); 87   $orders[] = $act_tag; 88   $orders[] = $channel_tag; 89   $orders[] = time(); 90   $newlen = array_merge($orders,$length[$x]); 91   if($count1 !== count($newlen)){ //如果商品字段的长度和商品的长度不等就证明用户有哪个字段没录入 92     $newrs = array(); 93     echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'请检查第,'.($x-1).'件商品!'.'导入失败!'."</font>"); </script>"; 94     fclose($handle); 95     exit(); 96   }else{ //start 97     $arrimport = array_combine($skeys,$newlen); //如果两个数组是相等的我就合并数组,并把导入csv里面的日期改为时间戳存储到数据库 98     if(!empty($arrimport['start_time'])){ $sta = strtotime($arrimport['start_time']); }else{ $sta=(int)0; } 99     if(!empty($arrimport['end_time'])){ $end = strtotime($arrimport['end_time']); }else{ $end=(int)0; } 100     $arrtime=array('start_time'=>$sta,'end_time'=>$end); 101     if(!empty($arrimport['start_time']) && !empty($arrimport['end_time'])){ 102     $newrs=array_merge($arrimport,$arrtime); 103   }else{ 104     $newrs = array(); 105     echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'请检查第,'.($x-1).'件商品!'.'导入失败!'."</font>"); </script>"; 106     fclose($handle); 107     exit(); 108   } 109   if(count($skeys) == count($newrs)){ 110     DB::insert('商品表', array_values($skeys)) 111       ->values(array_values($newrs)) 112       ->execute(); 113   } 114 } //end 115 } 116 } 117 if($row-1==(int)0){ 118   echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'您导入的商品为空!'."</font>"); </script>"; 119 }else{ 120 echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'成功导入'."<font color=#f00;>".($row-1)."</font>".'件商品!'."</font>"); 121 } 122 fclose($handle); 123 }

以下是简单导入:

 1 <form enctype="multipart/form-data" action="import.php" method="POST"> 
 2 导入模板 
 3 <label for="文件选择">文件选择:</label><input name="csv_goods" type="file" /> 
 4 <input type="submit" value="导入" name="import" /> 
 5 </form> 
 6 
 7 
 8 <?php 
 9 if (isset($_POST['import'])){ 
10     $file = $_FILES['csv_goods']; 
11     $file_type = substr(strstr($file['name'],'.'),1); 
12 
13     // 检查文件格式 
14     if ($file_type != 'csv'){ 
15         echo '文件格式不对,请重新上传!'; 
16         exit; 
17     } 
18     $handle = fopen($file['tmp_name'],"r"); 
19     $file_encoding = mb_detect_encoding($handle); 
20 
21     // 检查文件编码 
22     if ($file_encoding != 'ASCII'){ 
23         echo '文件编码错误,请重新上传!'; 
24         exit; 
25     } 
26 
27     $row = 0; 
28     while ($data = fgetcsv($handle,1000,',')){ 
29         //echo "<font color=red>$row</font>"; //可以知道总共有多少行 
30         $row++; 
31         if ($row == 1) 
32             continue; 
33             
34         $num = count($data); 
35         // 这里会依次输出每行当中每个单元格的数据 
36         for ($i=0; $i<$num; $i++){ 
37             echo $data[$i]."<br>"; 
38             // 在这里对数据进行处理 
39         } 
40     } 
41     fclose($handle); 
42 } 
43 ?>

地址:

http://www.jb51.net/article/46609.htm

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM