PHP 的 laravel 导出 csv 时,在 Windows 的 Micr Office 中出现乱码解决办法总结

2023-11-21 05:20

本文主要是介绍PHP 的 laravel 导出 csv 时,在 Windows 的 Micr Office 中出现乱码解决办法总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景:

一次使用 laravel 的 Excel Facades 时,测试同事发现在他的 Windows Micro Office Excel 中打开是乱码的 ,这是故事的开始。

下面是我使用 Excel 的方法:

$exportArr = [['1']
];
$top = ['test'];
array_unshift($exportArr, $top);
$fileName = 'xx';Excel::create($fileName, function($excel) use ($exportArr)
{$excel->sheet('sheet', function($sheet) use ($exportArr){$sheet->rows($exportArr);});
})->export('csv');

现象:只有在 Windows 的 Micro Office Excel 中打开是乱码,其他端都是OK的,这就很奇怪。

但是,将文件的编码格式改为 UTF-8 BOM 后,再打开就没有乱码了。看来跟这个 BOM有关系了。


百度一番后,需要了解以下知识点:

  1. BOM (Byte Order Mark)也是 Unicode 标准的一部分,通常BOM是用来标示Unicode纯文本字节流,Windows 使用 BOM 来区分输入的文本是使用哪种 Unicode 编码的(UTF-8,UTF-16BE,UTF-16LE),所以,它会在文本的开头自动加上 BOM的标识。这段整理自 「带 BOM 的 UTF-8」和「无 BOM 的 UTF-8」有什么区别?网页代码一般使用哪个? 来自 陈甫鸼 的回答。才会有网上说的这些问题: 
    1. 新建一个空的文本文档,却占用了 3 字节
    2. 一个特殊的空格ZERO WIDTH NO-BREAK SPACE
  2. 那么 BOM 在不同的编码格式中,输出到文件开头的字符是不一样的。对应关系可以参考 上面 2 [ 一个特殊的空格ZERO WIDTH NO-BREAK SPACE ] 的相关内容。为了方便查阅,盗图一下 
  3. BOM 在不同编码中的对应关系

  4.     UCS 编码中 有个字符 ZERO WIDTH NO-BREAK SPACE 意思就是 零宽度非换行空格。这个字符就是 BOM。在字节流中,用来标识字节流的顺序。具体可以百度了解一下,这里不详细说明。

了解了这些后,我们就知道需要将 输出的文本的格式切换为 UTF-8 BOM,这样 Windows 的 Office Excel 才能正常打开文本。

那么如果将 UTF-8 的编码格式转变为 UTF-8 BOM呢。下面是百度的结果,大家可以试试以下方法可以解决。

  1. laravel 导出csv文件 用excel打开中文乱码问题之BOM 这个主要是修改 laravel 第三方库的配置
  2. phpexcel导出excel中文乱码问题解决 这个主要是使用 PHP 的 ob_end_clean() 方法
  3. Laravel Excel 遇到的坑 这个是使用 iconv() 将输出的文本改变编码格式
  4. laravel-admin表格数据导出乱码问题解决 这个是利用 BOM 在 UTF-8 编码格式下输出文本的字符,来告诉 Windows 使用 UTF-8 BOM 编码
  5. 完美解决laravel-admin 导出excel文件中文乱码 这个跟 1 和 4 中的差不多,他也是修改源码,但是使用 BOM 在 UTF-8 编码格式下的字符,输出到文本的头部

但是这些方法都没有解决我使用上面的代码导出的文本在 Excel 中乱码的问题。但是,上面的几种方法,我尝试结合来一下,发现是可以解决的。看代码:


解法一:

Excel::create(iconv('UTF-8', 'GBK', $fileName), function($excel) use ($exportArr)
{print(chr(0xEF).chr(0xBB).chr(0xBF));$excel->sheet('sheet', function($sheet) use ($exportArr){$sheet->rows($exportArr);});
})->export('csv');

还有另外一种解决办法,请参考代码

解法二:

function setExportCSV($name, $type = 'csv')
{if (!$name)$name = "新建文件";if (preg_match('/Firefox/i', $_SERVER['HTTP_USER_AGENT'])) {$name = preg_replace("/ |\t|\"/", '', $name);header("Content-type:text/csv");header("Content-Disposition:attachment;filename=" . $name . "." . $type);header('Cache-Control:must-revalidate,post-check=0,pre-check=0');header('Expires:0');header('Pragma:public');} else if (preg_match('/Edge/i', $_SERVER['HTTP_USER_AGENT'])) {$name = preg_replace("/ |\t|\"/", '', $name);$name = urlencode($name);header("Content-type:application/octet-stream");header("Accept-Ranges:bytes");header("Content-type:application/vnd.ms-excel;charset=UTF-8");header("Content-Disposition:attachment;filename=" . $name . "." . $type);header('Content-Transfer-Encoding: binary');header("Pragma: no-cache");header("Expires: 0");} else {$name = preg_replace("/ |\t|\"/", '', $name) . '.' . $type;header("Content-type:application/octet-stream");header("Accept-Ranges:bytes");header("Content-type:application/vnd.ms-excel;charset=UTF-8");header("Content-Disposition:attachment;filename=" . urlencode($name));header('Content-Transfer-Encoding: binary');header("Pragma: no-cache");header("Expires: 0");}
}function exportCSV($exportData)
{foreach ($exportData as $key => $rt) {$a = implode('zqxddcghl', $rt);$b = str_replace(',', ',', $a);echo iconv('UTF-8', 'GBK//IGNORE', str_replace("\n", ' ', str_replace('"', '“', (str_replace('zqxddcghl', ',', $b)))) . "\n");}exit;
}

使用方法是:

setExportCSV($fileName);
exportCSV($exportArr);

到这里,这个问题已经解决了。如果文中,有什么出入的地方,还请不吝指教,谢谢。

对于第二种解决办法,等后面有时间了,再详细说明一下运行原理。

这篇关于PHP 的 laravel 导出 csv 时,在 Windows 的 Micr Office 中出现乱码解决办法总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/400095

相关文章

QT进行CSV文件初始化与读写操作

《QT进行CSV文件初始化与读写操作》这篇文章主要为大家详细介绍了在QT环境中如何进行CSV文件的初始化、写入和读取操作,本文为大家整理了相关的操作的多种方法,希望对大家有所帮助... 目录前言一、CSV文件初始化二、CSV写入三、CSV读取四、QT 逐行读取csv文件五、Qt如何将数据保存成CSV文件前言

Python运行中频繁出现Restart提示的解决办法

《Python运行中频繁出现Restart提示的解决办法》在编程的世界里,遇到各种奇怪的问题是家常便饭,但是,当你的Python程序在运行过程中频繁出现“Restart”提示时,这可能不仅仅是令人头疼... 目录问题描述代码示例无限循环递归调用内存泄漏解决方案1. 检查代码逻辑无限循环递归调用内存泄漏2.

关于pandas的read_csv方法使用解读

《关于pandas的read_csv方法使用解读》:本文主要介绍关于pandas的read_csv方法使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录pandas的read_csv方法解读read_csv中的参数基本参数通用解析参数空值处理相关参数时间处理相关

Redis在windows环境下如何启动

《Redis在windows环境下如何启动》:本文主要介绍Redis在windows环境下如何启动的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Redis在Windows环境下启动1.在redis的安装目录下2.输入·redis-server.exe

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为

MySQL错误代码2058和2059的解决办法

《MySQL错误代码2058和2059的解决办法》:本文主要介绍MySQL错误代码2058和2059的解决办法,2058和2059的错误码核心都是你用的客户端工具和mysql版本的密码插件不匹配,... 目录1. 前置理解2.报错现象3.解决办法(敲重点!!!)1. php前置理解2058和2059的错误