Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 603|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-29 13:39:18 | 显示全部楼层 |阅读模式

    问题一解决: 在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

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-16 07:00 , Processed in 0.067551 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表