ホームページ  >  記事  >  php教程  >  php导入csv文件以及碰到乱码解决方法

php导入csv文件以及碰到乱码解决方法

WBOY
WBOYオリジナル
2016-06-06 19:45:401158ブラウズ

今天主要是想写一个php导入csv文件的方法,其实网上一搜一大把。都是可以实现怎么去导入的。但是我导入的时候遇到了两个问题,一个是在windows上写代码的时候测试发生了乱码问题,然后解决了。第二个是提交到linux系统上的时候又发生了乱码。我开始还不清楚

    今天主要是想写一个php导入csv文件的方法,其实网上一搜一大把。都是可以实现怎么去导入的。但是我导入的时候遇到了两个问题,一个是在windows上写代码的时候测试发生了乱码问题,然后解决了。第二个是提交到linux系统上的时候又发生了乱码。我开始还不清楚是乱码的原因,一开始我还以为是代码svn提交发生的错误,到最后我在我的一个群里提问了一下,一朋友是做phpcms的,他说他遇到从Windows提交到Linux的时候刚开始也总是发生错误,后来排查原因就是乱码导致成的。下面切入正题看怎么解决两个问题的吧!

问题一解决:

    php读取csv文件,在windows上出现中文读取不到的情况,本人立马想到一个函数mb_convert_encoding();作如下设置 $str = mb_convert_encoding($str, "UTF-8", "GBK");然后就可以了。当然你也可以用iconv();作如下设置iconv(‘GBK’,”UTF-8//TRANSLIT//IGNORE”,$str);这两个函数来解决在windows上面发生乱码的问题。

问题二解决:

   php读取csv文件,在linux上出现中文读取不到的情况,百度,google后找到解决办法

  就是添加了一行代码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’);

之所以给大家讲 setlocale()这个函数,是因为我导入csv文件到linux系统的时候发生了乱码,包括用了mb_convert_encoding()iconv()两个函数都是没搞定最后问题的。最后就加了这一句setlocale(LC_ALL, ‘zh_CN’);加在导入csv文件开始的代码前面就轻松搞定了,然后我又找了一下资料,发现fgetcsv()函数对区域设置是敏感的。比如说 LANG 设为 en_US.UTF-8 的话,单字节编码的文件就会出现读取错误,所以我们需要对其进行区域性的设置。特分享给大家。

我还尝试用了以下代码也没能搞定,这些都是生成csv文件的header的设置。可能在我这里不起作用,但是在你那里也说不定哦。所以我都整理出来,尽可能的帮助遇到导入csv文件乱码的同行,因为在没办法的情况下真的太难处理了。大家可以都试试!总有一个是属于你的。。。

<?php $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 运行时配置选项。

   <?php setlocale(LC_ALL, 'zh_CN');  //设置地区信息(地域信息)
    $file = $_FILES['files'];
    $file_type = substr(strstr($file['name'],'.'),1);
   if ($file_type != 'csv'){
   echo "<script type=\"text/javascript\">alert(\"文件格式错误,请重新上传!\"); "; 
   exit;
   }
   $handle = fopen($file['tmp_name'],"r");
   $file_encoding = mb_detect_encoding($handle);
   if ($file_encoding != 'ASCII'){
   echo "<script type='\"text/javascript\"'>alert(\"文件编码错误,请重新上传!\"); </script>"; 
   exit;
   }
  $row = 0;
  $str="";
  $sy="";
  while ($data = fgetcsv($handle,1000,',')){
    $row++;
    if ($row == 0)
    continue;
    $num = count($data);
    for ($i=0; $ifrom('字段表')->fetch_all();
 foreach ($arrtagname as $value) {
  $arrfileds[$value['fileds_tags']] = $value['fileds_name'];
 }
  foreach ($fileds as $v)
   {
    $temarr= explode('-', $v);
    if (isset($temarr[0]) && !empty($temarr[0])) {
     if (isset($temarr[1]) && !empty($temarr[1])) {
      if ($temarr[1] == 'wenben') {
       $arrtitle[] = $arrfileds[$temarr[0]].'文本';
      }
     } else {
      if ($temarr[0] != 'pic') {   //是取出字段是图片就给去掉
       $arrtitle[] = $arrfileds[$temarr[0]];
      }
     }
    }
   
   }

   $skey = array();
   $order = array();
   $order[] = 'act_tag';
   $order[] = 'channel_tag';
   $order[] = 'created_time';
   $order[] = 'orderby';
   $rows ='';
   $f = $co/$num;//求出有多少件商品
   for($p=0;$p<count db::select>from('字段表')->where('字段名称', '=', $arrtitle[$p])->fetch_row();
   $rows .= $skey[$p]['字段标识'].'|';
   }
   if($rows){ $rows = rtrim($rows,'|'); }
   if(!empty($rows)){ $exrows = explode('|',$rows); }else{ $exrows = array(); }
   $skeys = array_merge($order,$exrows);
   $count1 = count($skeys); //字段的个数
    if(!empty($length)){
    for($x=1;$xalert(\"<font color="#f00;">".'请检查第,'.($x-1).'件商品!'.'导入失败!'."</font>"); "; 
    fclose($handle);
    exit();
    }else{ //start
  $arrimport = array_combine($skeys,$newlen); //如果两个数组是相等的我就合并数组,并把导入csv里面的日期改为时间戳存储到数据库
if(!empty($arrimport['start_time'])){ $sta = strtotime($arrimport['start_time']); }else{ $sta=(int)0; }
if(!empty($arrimport['end_time'])){ $end = strtotime($arrimport['end_time']); }else{ $end=(int)0; }
$arrtime=array('start_time'=>$sta,'end_time'=>$end);
  if(!empty($arrimport['start_time']) && !empty($arrimport['end_time'])){
  $newrs=array_merge($arrimport,$arrtime);
  }else{
  $newrs = array();
	echo "<script type='\"text/javascript\"'>alert(\"<font color=#f00;>".'请检查第,'.($x-1).'件商品!'.'导入失败!'.""); </script>"; 
  fclose($handle);
  exit();
  }
  if(count($skeys) == count($newrs)){
    DB::insert('商品表', array_values($skeys))
    ->values(array_values($newrs))
    ->execute();
          }
    } //end
        }
  } 
  if($row-1==(int)0){
echo "<script type='\"text/javascript\"'>alert(\"<font color=#f00;>".'您导入的商品为空!'.""); </script>";  
            }else{ 
echo "<script type='\"text/javascript\"'>alert(\"<font color=#f00;>".'成功导入'."<font color=#f00;>".($row-1)."".'件商品!'."");
      }
   fclose($handle);
   }
?></script></count>

以上是我工作需要所做的csv导入处理,可能和你的导入方式不同,但是部分代码总会对你有帮助!

以下是简单导入:


导入模板
$row"; //可以知道总共有多少行 $row++; if ($row == 1) continue; $num = count($data); // 这里会依次输出每行当中每个单元格的数据 for ($i=0; $i"; // 在这里对数据进行处理 } } fclose($handle); } ?>

方法二:

<?php $fp = fopen('csv文件名', 'w');
$rs = mysql_query('select * from tbl_name');
while($row = mysql_fetch_assoc($rs) {
  fputcsv($fp, $row);
}
fclose($fp);
?>


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。