csv encode and export
/** | |
* csv data encode | |
* var data = [[1850, 20, 0, 1, 1017281], [1850, 20, 0, 2, 1003841]]; | |
* encode(data) | |
* encode(data,{ header: ["year", "age", "status", "sex", "population"] }) | |
* encode([{age:xx,name:'xxx'}], {header:true}) | |
* options:{ delimiter:'分隔符',newline:换行符,skip:头部跳过数量,header:Object或者arrat } | |
*/ | |
const CELL_DELIMITERS = [',', ';', '\t', '|', '^'] | |
const LINE_DELIMITERS = ['\r\n', '\r', '\n'] | |
const STANDARD_ENCODE_OPTS = { | |
delimiter: CELL_DELIMITERS[0], | |
newline: LINE_DELIMITERS[0], | |
skip: 0, | |
limit: false, | |
header: false | |
} | |
const quoteMark = '"' | |
const doubleQuoteMark = '""' | |
const quoteRegex = /"/g | |
const getType = (obj) => Object.prototype.toString.call(obj).slice(8, -1) | |
const getLimit = (limit, len) => limit === false ? len : limit | |
function encodeCells (line, delimiter, newline) { | |
let row = line.slice(0) | |
for (let i = 0, len = row.length; i < len; i++) { | |
if (typeof row[i] !== 'string') { | |
continue | |
} | |
if (row[i].indexOf(quoteMark) !== -1) { | |
row[i] = row[i].replace(quoteRegex, doubleQuoteMark) | |
} | |
if (row[i].indexOf(delimiter) !== -1 || row[i].indexOf(newline) !== -1) { | |
row[i] = quoteMark + row[i] + quoteMark | |
} | |
} | |
return row.join(delimiter) | |
} | |
function encodeArrays (coll, opts, fn) { | |
let delimiter = opts.delimiter | |
let newline = opts.newline | |
if (opts.header && getType(opts.header) === 'Array') { | |
fn(encodeCells(opts.header, delimiter, newline)) | |
} | |
for (let cur = 0, lim = getLimit(opts.limit, coll.length); cur < lim; cur++) { | |
fn(encodeCells(coll[cur], delimiter, newline)) | |
} | |
return true | |
} | |
function encodeObjects (coll, opts, fn) { | |
let delimiter = opts.delimiter | |
let newline = opts.newline | |
let header | |
let row | |
header = [] | |
row = [] | |
for (let key in coll[0]) { | |
header.push(key) | |
row.push(coll[0][key]) | |
} | |
if (opts.header === true) { | |
fn(encodeCells(header, delimiter, newline)) | |
} else if (getType(opts.header) === 'Array') { | |
fn(encodeCells(opts.header, delimiter, newline)) | |
} | |
fn(encodeCells(row, delimiter)) | |
for (let cur = 1, lim = getLimit(opts.limit, coll.length); cur < lim; cur++) { | |
row = [] | |
for (let key = 0, len = header.length; key < len; key++) { | |
row.push(coll[cur][header[key]]) | |
} | |
fn(encodeCells(row, delimiter, newline)) | |
} | |
return true | |
} | |
export function encodeCsv (coll, opts, fn) { | |
let lines | |
if (getType(opts) === 'Function') { | |
fn = opts | |
opts = {} | |
} else if (getType(fn) !== 'Function') { | |
lines = [] | |
fn = lines.push.bind(lines) | |
} | |
opts = Object.assign({}, STANDARD_ENCODE_OPTS, opts) | |
if (opts.skip > 0) { | |
coll = coll.slice(opts.skip) | |
} | |
return (getType(coll[0]) === 'Array' ? encodeArrays : encodeObjects)(coll, opts, fn) && | |
(lines.length > 0 ? lines.join(opts.newline) : true) | |
} |
export function downloadCsv (csvFile, filename) { | |
filename = `${filename}.csv` | |
let blob = new Blob([csvFile], { type: 'text/csv;charset=utf-8;' }) | |
if (navigator.msSaveBlob) { // IE 10+ | |
navigator.msSaveBlob(blob, filename) | |
} else { | |
let link = document.createElement('a') | |
if (link.download !== undefined) { // feature detection | |
// Browsers that support HTML5 download attribute | |
var url = URL.createObjectURL(blob) | |
link.setAttribute('href', url) | |
link.setAttribute('download', filename) | |
link.style.visibility = 'hidden' | |
document.body.appendChild(link) | |
link.click() | |
document.body.removeChild(link) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment