mirror of
https://gitee.com/x-extends/vxe-table-plugin-export-xlsx.git
synced 2026-01-21 05:21:33 +08:00
203 lines
6.3 KiB
TypeScript
203 lines
6.3 KiB
TypeScript
import XEUtils from 'xe-utils/methods/xe-utils'
|
|
import VXETable from 'vxe-table/lib/vxe-table'
|
|
import XLSX from 'xlsx'
|
|
|
|
function getSeq($table: any, row: any, rowIndex: number, column: any, columnIndex: number) {
|
|
// 在 v3.0 中废弃 startIndex、indexMethod
|
|
let seqOpts = $table.seqOpts
|
|
let seqMethod = seqOpts.seqMethod || column.indexMethod
|
|
return seqMethod ? seqMethod({ row, rowIndex, column, columnIndex }) : ((seqOpts.startIndex || $table.startIndex) + rowIndex + 1)
|
|
}
|
|
|
|
function toBuffer(wbout: any) {
|
|
let buf = new ArrayBuffer(wbout.length)
|
|
let view = new Uint8Array(buf)
|
|
for (let index = 0; index !== wbout.length; ++index) view[index] = wbout.charCodeAt(index) & 0xFF
|
|
return buf
|
|
}
|
|
|
|
function exportXLSX(params: any) {
|
|
const { $table, options, columns, datas } = params
|
|
const { sheetName, type, isHeader, isFooter, original, message, footerFilterMethod } = options
|
|
const colHead: any = {}
|
|
const footList: any[] = []
|
|
if (isHeader) {
|
|
columns.forEach((column: any) => {
|
|
colHead[column.id] = XEUtils.toString(original ? column.property : column.getTitle())
|
|
})
|
|
}
|
|
const rowList: any[] = datas.map((row: any, rowIndex: number) => {
|
|
const item: any = {}
|
|
columns.forEach((column: any, columnIndex: number) => {
|
|
let cellValue
|
|
const property = column.property
|
|
const isIndex = column.type === 'seq' || column.type === 'index'
|
|
if (!original || isIndex) {
|
|
cellValue = isIndex ? getSeq($table, row, rowIndex, column, columnIndex) : row[column.id]
|
|
} else {
|
|
cellValue = XEUtils.get(row, property)
|
|
}
|
|
item[column.id] = cellValue
|
|
})
|
|
return item
|
|
})
|
|
if (isFooter) {
|
|
const footerData: any[] = $table.footerData
|
|
const footers: any[] = footerFilterMethod ? footerData.filter(footerFilterMethod) : footerData
|
|
footers.forEach((rows: any[]) => {
|
|
const item: any = {}
|
|
columns.forEach((column: any) => {
|
|
item[column.id] = rows[$table.$getColumnIndex(column)] || ''
|
|
})
|
|
footList.push(item)
|
|
})
|
|
}
|
|
const book = XLSX.utils.book_new()
|
|
const sheet = XLSX.utils.json_to_sheet((isHeader ? [colHead] : []).concat(rowList).concat(footList), { skipHeader: true })
|
|
// 转换数据
|
|
XLSX.utils.book_append_sheet(book, sheet, sheetName)
|
|
const wbout = XLSX.write(book, { bookType: type, bookSST: false, type: 'binary' })
|
|
const blob = new Blob([toBuffer(wbout)], { type: 'application/octet-stream' })
|
|
// 保存导出
|
|
downloadFile(blob, options)
|
|
if (message !== false) {
|
|
$table.$XModal.message({ message: i18n('vxe.table.expSuccess'), status: 'success' })
|
|
}
|
|
}
|
|
|
|
function downloadFile(blob: Blob, options: any) {
|
|
if (window.Blob) {
|
|
const { filename, type } = options
|
|
if (navigator.msSaveBlob) {
|
|
navigator.msSaveBlob(blob, `${filename}.${type}`)
|
|
} else {
|
|
var linkElem = document.createElement('a')
|
|
linkElem.target = '_blank'
|
|
linkElem.download = `${filename}.${type}`
|
|
linkElem.href = URL.createObjectURL(blob)
|
|
document.body.appendChild(linkElem)
|
|
linkElem.click()
|
|
document.body.removeChild(linkElem)
|
|
}
|
|
} else {
|
|
console.error(i18n('vxe.error.notExp'))
|
|
}
|
|
}
|
|
|
|
function replaceDoubleQuotation(val: string) {
|
|
return val.replace(/^"/, '').replace(/"$/, '')
|
|
}
|
|
|
|
function parseCsv(columns: any[], content: string) {
|
|
const list: string[] = content.split('\n')
|
|
const fields: any[] = []
|
|
const rows: any[] = []
|
|
if (list.length) {
|
|
const rList: string[] = list.slice(1)
|
|
list[0].split(',').forEach((val: string) => {
|
|
const field: string = replaceDoubleQuotation(val)
|
|
if (field) {
|
|
fields.push(field)
|
|
}
|
|
})
|
|
rList.forEach((r: string) => {
|
|
if (r) {
|
|
const item: any = {}
|
|
r.split(',').forEach((val: string, colIndex: number) => {
|
|
item[fields[colIndex]] = replaceDoubleQuotation(val)
|
|
})
|
|
rows.push(item)
|
|
}
|
|
})
|
|
}
|
|
return { fields, rows }
|
|
}
|
|
|
|
function checkImportData(columns: any[], fields: string[], rows: any[]) {
|
|
let tableFields: string[] = []
|
|
columns.forEach((column: any) => {
|
|
let field: string = column.property
|
|
if (field) {
|
|
tableFields.push(field)
|
|
}
|
|
})
|
|
return tableFields.every((field: string) => fields.includes(field))
|
|
}
|
|
|
|
function importXLSX(params: any) {
|
|
const { $table, columns, options, file } = params
|
|
const { _importCallback, _importResolve } = $table
|
|
const fileReader = new FileReader()
|
|
fileReader.onload = (e: any) => {
|
|
const workbook = XLSX.read(e.target.result, { type: 'binary' })
|
|
const csvData: string = XLSX.utils.sheet_to_csv(workbook.Sheets.Sheet1)
|
|
const rest: any = parseCsv(columns, csvData)
|
|
const { fields, rows } = rest
|
|
const status = checkImportData(columns, fields, rows)
|
|
if (status) {
|
|
$table.createData(rows)
|
|
.then((data: any[]) => {
|
|
if (options.mode === 'append') {
|
|
$table.insertAt(data, -1)
|
|
} else {
|
|
$table.reloadData(data)
|
|
}
|
|
})
|
|
if (options.message !== false) {
|
|
$table.$XModal.message({ message: i18n('vxe.table.impSuccess'), status: 'success' })
|
|
}
|
|
} else if (options.message !== false) {
|
|
$table.$XModal.message({ message: i18n('vxe.error.impFields'), status: 'error' })
|
|
}
|
|
if (_importResolve) {
|
|
_importResolve(status)
|
|
$table._importResolve = null
|
|
} else if (_importCallback) {
|
|
// 已废弃
|
|
_importCallback(status)
|
|
$table._importCallback = null
|
|
}
|
|
}
|
|
fileReader.readAsBinaryString(file)
|
|
}
|
|
|
|
function handleImportEvent(params: any) {
|
|
if (params.options.type === 'xlsx') {
|
|
importXLSX(params)
|
|
return false
|
|
}
|
|
}
|
|
|
|
function handleExportEvent(params: any) {
|
|
if (params.options.type === 'xlsx') {
|
|
exportXLSX(params)
|
|
return false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 基于 vxe-table 表格的增强插件,支持导出 xlsx 格式
|
|
*/
|
|
export const VXETablePluginExportXLSX: any = {
|
|
install(xtable: typeof VXETable) {
|
|
Object.assign(xtable.types, { xlsx: 1 })
|
|
xtable.interceptor.mixin({
|
|
'event.import': handleImportEvent,
|
|
'event.export': handleExportEvent
|
|
})
|
|
VXETablePluginExportXLSX.t = xtable.t
|
|
}
|
|
}
|
|
|
|
function i18n(key: string) {
|
|
if (VXETablePluginExportXLSX.t) {
|
|
return VXETablePluginExportXLSX.t(key)
|
|
}
|
|
}
|
|
|
|
if (typeof window !== 'undefined' && window.VXETable) {
|
|
window.VXETable.use(VXETablePluginExportXLSX)
|
|
}
|
|
|
|
export default VXETablePluginExportXLSX
|