PHP結(jié)合vue導(dǎo)出excel出現(xiàn)亂碼的解決方法分享
在這之前我們先回顧以前用php導(dǎo)出excel,我直接寫成方法在這里:
public static function phpExcelList($field, $list, $title='文件',$file_time){ $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); foreach ($list as $key => $value) { foreach ($field as $k => $v) { if ($key == 0) { $sheet->setCellValue($k . '1', $v[1]); } $i = $key + 2; //表格是從2開(kāi)始的 $sheet->setCellValue($k . $i, $value[$v[0]]); } } ob_clean(); header("Content-type:application/vnd.ms-excel;charset=UTF-8"); header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename="'.$title.'.csv"'); header('Cache-Control: max-age=0'); $writer = new Csv($spreadsheet); $writer->save('php://output'); exit; }
一般有設(shè)置charset基本在前端就沒(méi)啥問(wèn)題,問(wèn)題就在于vue導(dǎo)出時(shí)就出現(xiàn)亂碼了,有可能是這個(gè),大多數(shù)網(wǎng)友的解決方案就是在請(qǐng)求里邊加上參數(shù):responseType: 'blob', // 表明返回服務(wù)器返回的數(shù)據(jù)類型,但這里我已經(jīng)提前申明返回的數(shù)據(jù)是正常的,這時(shí)候又會(huì)咋樣呢?
咱們?cè)囋囉脟?guó)產(chǎn)的wps打開(kāi)吧:
咦?沒(méi)問(wèn)題?再用office打開(kāi):啊哈》》?what?
那問(wèn)題出在哪里呢?讀入的文件是utf-8格式,下載下來(lái)Excel打開(kāi)亂碼,但是用其他編輯器打開(kāi)并不是亂碼,一開(kāi)始解決問(wèn)題的思路是,下載文件的時(shí)候,是不是沒(méi)有指定編碼方式,導(dǎo)致文件編碼方式不對(duì),于是乎使用了Blob里的type參數(shù),硬塞了一個(gè)類型以及編碼方式,但是這種方法似乎并不管用,仔細(xì)讀了官方文檔之后,關(guān)于type的解讀如下:
type,默認(rèn)值為 “”,它代表了將會(huì)被放入到blob中的數(shù)組內(nèi)容的MIME類型。
這里明確表明,此type只是一個(gè)類型標(biāo)記,并不會(huì)起到轉(zhuǎn)碼的作用,想想也是,blob僅僅是內(nèi)存里開(kāi)辟的0,1代碼,怎么可能在下載的過(guò)程中去解碼編碼呢?
發(fā)現(xiàn)這其實(shí)是微軟家的坑,微軟家發(fā)明了一個(gè)東西叫bom頭,關(guān)于bom頭:
類似WINDOWS自帶的記事本等軟件,在保存一個(gè)以UTF-8編碼的文件時(shí),會(huì)在文件開(kāi)始的地方插入U(xiǎn)TF-8 BOM頭。記事本等編輯器通過(guò)它來(lái)識(shí)別這個(gè)文件是否以UTF-8編碼(當(dāng)然即便沒(méi)有UTF-8 BOM頭記事本也能通過(guò)其它方式正確識(shí)別UTF-8編碼)。
那么如果一個(gè)UTF-8編碼的字符串的開(kāi)頭處沒(méi)有BOM頭又會(huì)發(fā)生什么?答:不認(rèn)識(shí)你,亂碼給你看
所以我們?cè)谶@需要手動(dòng)加一個(gè)微軟看得懂的BOM頭:
window.URL.createObjectURL(new Blob(['\uFEFF' + content]))
總的代碼示例如下,不懂可以直接抄:
this.$http.get(common.webapi+'/api/exportExcel',{params:{參數(shù)名稱:參數(shù)值}}, {emulateJSON:true,responseType: 'blob'}).then((res)=>{ if(res.data){ const link = document.createElement('a');// 創(chuàng)建a標(biāo)簽 let blob = new Blob(['\uFEFF' + res.data],{type: 'application/vnd.ms-excel;'}); // 設(shè)置文件類型并在返回值前加bom頭,避免亂碼 link.style.display = "none"; link.href = URL.createObjectURL(blob); // 創(chuàng)建URL link.setAttribute("download", "數(shù)據(jù)"+ this.$moment(new Date().getTime()).format("YYYY-MM-DD")+'.csv'); document.body.appendChild(link); link.click(); document.body.removeChild(link); //如果不會(huì)出現(xiàn)亂碼,直接一句代碼搞定:this.$fileDownload(res.data, "發(fā)票數(shù)據(jù)"+ this.$moment(new Date().getTime()).format("YYYY-MM-DD")+'.csv') } })
//如果不會(huì)出現(xiàn)亂碼,直接一句代碼搞定:this.$fileDownload(res.data, "數(shù)據(jù)"+ this.$moment(new Date().getTime()).format("YYYY-MM-DD")+'.csv'),接下來(lái)就是見(jiàn)證奇跡的時(shí)刻:
到此這篇關(guān)于PHP結(jié)合vue導(dǎo)出excel出現(xiàn)亂碼的解決方法分享的文章就介紹到這了,更多相關(guān)PHP導(dǎo)出excel出現(xiàn)亂碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PHP在不同頁(yè)面間傳遞Json數(shù)據(jù)示例代碼
本文為大家介紹下PHP如何在不同頁(yè)面間傳遞Json數(shù)據(jù),具體實(shí)現(xiàn)如下,感興趣的朋友可以參考下哈,希望對(duì)大家有所幫助2013-06-06PHP 和 MySQL 開(kāi)發(fā)的 8 個(gè)技巧
PHP 和 MySQL 開(kāi)發(fā)的 8 個(gè)技巧...2007-01-01PHP基于MySQL數(shù)據(jù)庫(kù)實(shí)現(xiàn)對(duì)象持久層的方法
這篇文章主要介紹了PHP基于MySQL數(shù)據(jù)庫(kù)實(shí)現(xiàn)對(duì)象持久層的方法,實(shí)例分析了php實(shí)現(xiàn)持久層的相關(guān)技巧,需要的朋友可以參考下2015-06-06解決php中Cannot send session cache limiter 的問(wèn)題的方法
解決php中Cannot send session cache limiter 的問(wèn)題的方法...2007-04-04PHP實(shí)現(xiàn)自動(dòng)登入google play下載app report的方法
這篇文章主要介紹了PHP實(shí)現(xiàn)自動(dòng)登入google play下載app report的方法,較為詳細(xì)的講述了登陸下載APP及對(duì)應(yīng)的實(shí)現(xiàn)代碼,具有不錯(cuò)的實(shí)用價(jià)值,需要的朋友可以參考下2014-09-09