PapaParse 这个插件虽说强大,可以快速将 CSV 文件转为 JSON 格式来渲染表格,但是某些地方真的让人很难受,比如它自带的 encoding 配置只能对通过 input 上传的本地文件起作用,而通过 URL 远程取到的文件不支持…
解决方案
先用 XMLHttpRequest() 获取到文件,然后设置 FileReader() 改变文件的编码,最后使用 PapaParse 直接解析。
要改变文件编码得先知道文件类型,这里给出我的两个解决方案,任选其一即可
使用 jschardet 插件解决
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   |  function checkEncoding(path) {                             return new Promise(function (resolve) {                    $.get(path, function (data, status) {             if (status == 'success') {                 var encoding = jschardet.detect(data);                 encoding = encoding.encoding;                 if (encoding === 'windows-1252') {                         encoding = 'GB2312';                 } else if (encoding === 'ascii') {                     encoding = 'UTF-8';                 }                 resolve(encoding);                                 }         });     }); }
 
  | 
 
好处是在前端就能应对大多数情况,但有些文件会识别失败…
在后端用 C# 解决:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
   | using System; using System.IO; using System.Text; using System.Web;
  public class CheckEncoding : IHttpHandler {
      public void ProcessRequest(HttpContext context) {         context.Response.ContentType = "text/plain";         var path = context.Request["path"];         try {             string ReadPath = HttpContext.Current.Server.MapPath("~/" + path + "");             byte[] bom = File.ReadAllBytes(ReadPath);             var encoding = GetBytesEncoding(bom);             context.Response.Write(encoding.BodyName);         } catch (Exception e) {             context.Response.Write("{\"fail\":\"" + e + "\"}");         }     }
      public static Encoding GetBytesEncoding(byte[] bs) {         int len = bs.Length;         if (len >= 3 && bs[0] == 0xEF && bs[1] == 0xBB && bs[2] == 0xBF) {             return Encoding.GetEncoding("gbk");         }         int[] cs = { 7, 5, 4, 3, 2, 1, 0, 6, 14, 30, 62, 126 };         for (int i = 0; i < len; i++) {             int bits = -1;             for (int j = 0; j < 6; j++) {                 if (bs[i] >> cs[j] == cs[j + 6]) {                     bits = j;                     break;                 }             }             if (bits == -1) {                 return Encoding.GetEncoding("gbk");             }             while (bits-- > 0) {                 i++;                 if (i == len || bs[i] >> 6 != 2) {                     return Encoding.GetEncoding("gbk");                 }             }         }         return Encoding.UTF8;     }
      public bool IsReusable {         get {             return false;         }     }
  }
   | 
 
完美解决
gb2312 加 utf-8 格式就能解决我这边绝大多数的中文编码问题,在无 BOM 码的情况下只判断是否为 utf-8 还是相对容易点的
成功解析
解析 CSV 文件,将其转为 JSON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   |  function parseCSV(path, encoding) {                        return new Promise(function (resolve) {                             let request = new XMLHttpRequest();         request.open('GET', path, true);                       request.responseType = 'blob';         request.onload = () => {             let file = request.response;             let reader = new FileReader();             reader.readAsText(file, encoding);                     reader.onload = () => {                 Papa.parse(reader.result, {                                complete: function (results) {                         resolve(results.data);                     }                 });             }         }         request.send();     }) }
 
  | 
 
async 的使用
1 2 3 4 5 6 7 8
   | async function main(path){             let encoding = await checkEncoding(path);          let criteriaAnswer = await parseCSV(path, encoding);          paintingTable(criteriaAnswer,"teacherPaperAnswer");  }
  | 
 
JSON 文件渲染 CSV 表格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   |  function paintingTable(File, location) {     $("#" + location + "").empty();     let table = '<table class="table table-bordered" style="zoom:0.8";>';     for (let j = 0; j < File.length; j++) {         if (j == 0) {             table += '<thead><tr style="white-space: nowrap;"><th scope="col">#</th>';             for (let k in File[j]) {                 table += '<th scope="col">' + k + '</th>';             }             table += '</tr></thead><tbody style="white-space: pre;">';         }         table += '<tr><th scope="row" style="vertical-align: middle;">' + Number(j + 1) + '</th>';         for (let k in File[j]) {             table += '<td style="vertical-align: middle; padding:0 20px; border: inset;background:#FFFFFF;"><div style="text-align:left;">' + File[j][k] + '</div></td>';         }         table += '</tr>';     }     table += '</tbody>';     $("#" + location + "").append(table); }
 
  | 
 
最后赠送一个 JSON 文件渲染 CSV 表格