分享一下 xlsx 这个库的常见使用场景,仅代表个人使用习惯,不喜勿喷
一、useExcel Hook封装
import { getTypeOf, isAvailableArr } from '@/utils'
import { message } from 'antd'
import type {
BookType,
ColInfo,
Range,
RowInfo,
Sheet2JSONOpts,
WorkBook,
} from 'xlsx'
import * as XLSX from 'xlsx'
// 导出文件配置
export type IExportConfig = {
name?: string // 导出文件名称
bookType?: BookType // 导出文件类型
sheetName?: string // sheet名称
errorMsg?: string // 错误提示
headers?: Record<string, string> // 自定义表头,导出的文件里面只有在定义中的字段,并且如果数据为空的话,只生成一个表头。示例:{id: 'ID', name: '链接名称', site_type: '官网类型'}
merges?: Range[] // 单元格合并
colInfo?: ColInfo[] // 列属性
rowInfo?: RowInfo[] // 行属性
}
// 多sheet导出
export type IExtraSheetConfig = {
name?: string // 导出文件名称
bookType?: BookType // 导出文件类型
sheets: ({ json: any[] } & Omit<IExportConfig, 'name' | 'bookType'>)[]
}
/**
* @desc 自定义导出文件hook
*/
const useExcel = () => {
/**
* @desc 一维数组导出Excel文件
*
* 此函数将一个一维数组转换为Excel文件并下载
* 支持自定义表头、单元格合并、列属性和行属性
*
* @param {any[]} json - 要导出的数据数组
* @param {IExportConfig} config - 导出配置项
* @param {string} [config.name='导出'] - 导出文件名称
* @param {BookType} [config.bookType='xlsx'] - 导出文件类型
* @param {string} [config.sheetName='Sheet1'] - 工作表名称
* @param {Record<string, string>} [config.headers] - 自定义表头映射
* @param {Range[]} [config.merges] - 单元格合并范围
* @param {ColInfo[]} [config.colInfo] - 列属性配置
* @param {RowInfo[]} [config.rowInfo] - 行属性配置
* @returns {void}
*/
function exportJson2Excel<T = any>(json: T[], config?: IExportConfig) {
const {
name = '导出',
sheetName = 'Sheet1',
bookType = 'xlsx',
headers,
merges,
colInfo,
rowInfo,
} = config || {}
let lists = [...json]
if (
headers &&
getTypeOf(headers) === 'Object' &&
isAvailableArr(Object.keys(headers))
) {
// 没有数据的时候用header去生成一个空表头
if (!isAvailableArr(lists)) {
const headersField = Object.values(headers)
const headerObj: Record<string, any> = {}
headersField.forEach((f) => {
headerObj[f] = null
})
lists = [headerObj as T]
} else {
// 有数据的时候根据header去生成
const headerFields = Object.entries(headers)
lists = json.map((j) => {
const obj: Record<string, any> = {}
for (const [key, value] of headerFields) {
obj[value] = j[key as keyof T] ?? null
}
return obj
}) as T[]
}
}
const wb = XLSX.utils.book_new()
const ws = XLSX.utils.json_to_sheet(lists)
if (merges) {
ws['!merges'] = merges
}
if (colInfo) {
ws['!cols'] = colInfo
}
if (rowInfo) {
ws['!rows'] = rowInfo
}
XLSX.utils.book_append_sheet(wb, ws, sheetName)
XLSX.writeFile(wb, `${name}.${bookType}`, { bookType })
}
/**
* @desc 一维数组多sheet导出Excel文件
*
* 此函数将多个一维数组分别放在不同的工作表中导出为一个Excel文件
* 支持自定义表头、单元格合并、列属性和行属性
*
* @param {IExtraSheetConfig} params - 多sheet导出配置项
* @param {string} [params.name='导出'] - 导出文件名称
* @param {BookType} [params.bookType='xlsx'] - 导出文件类型
* @param {Array} params.sheets - 工作表配置数组
* @param {any[]} params.sheets[].json - 要导出的数据数组
* @param {string} [params.sheets[].sheetName] - 工作表名称
* @param {Record<string, string>} [params.sheets[].headers] - 自定义表头映射
* @param {Range[]} [params.sheets[].merges] - 单元格合并范围
* @param {ColInfo[]} [params.sheets[].colInfo] - 列属性配置
* @param {RowInfo[]} [params.sheets[].rowInfo] - 行属性配置
* @returns {void}
*/
function exportJson2ExcelSheets<T = any>(params: IExtraSheetConfig) {
const { name = '导出', bookType = 'xlsx', sheets } = params || {}
const wb = XLSX.utils.book_new()
if (isAvailableArr(sheets)) {
sheets?.forEach((s) => {
const { json, headers, merges, colInfo, rowInfo, sheetName } = s || {}
let lists = [...json]
if (
headers &&
getTypeOf(headers) === 'Object' &&
isAvailableArr(Object.keys(headers))
) {
// 没有数据的时候用header去生成一个空表头
if (!isAvailableArr(lists)) {
const headersField = Object.values(headers)
const headerObj: Record<string, any> = {}
headersField.forEach((f) => {
headerObj[f] = null
})
lists = [headerObj as T]
} else {
// 有数据的时候根据header去生成
const headerFields = Object.entries(headers)
lists = json.map((j) => {
const obj: Record<string, any> = {}
for (const [key, value] of headerFields) {
obj[value] = j[key] ?? null
}
return obj
}) as T[]
}
}
const ws = XLSX.utils.json_to_sheet(lists)
if (merges) {
ws['!merges'] = merges
}
if (colInfo) {
ws['!cols'] = colInfo
}
if (rowInfo) {
ws['!rows'] = rowInfo
}
XLSX.utils.book_append_sheet(wb, ws, sheetName)
})
} else {
const ws = XLSX.utils.json_to_sheet([])
XLSX.utils.book_append_sheet(wb, ws)
}
XLSX.writeFile(wb, `${name}.${bookType}`, { bookType })
}
/**
* @desc 二维数组导出Excel文件
*
* 此函数将一个二维数组转换为Excel文件并下载
* 支持单元格合并、列属性和行属性
*
* @param {any[][]} aoas - 要导出的二维数组
* @param {IExportConfig} config - 导出配置项
* @param {string} [config.name='导出'] - 导出文件名称
* @param {BookType} [config.bookType='xlsx'] - 导出文件类型
* @param {string} [config.sheetName='Sheet1'] - 工作表名称
* @param {Range[]} [config.merges] - 单元格合并范围
* @param {ColInfo[]} [config.colInfo] - 列属性配置
* @param {RowInfo[]} [config.rowInfo] - 行属性配置
* @returns {void}
*/
function exportAoa2Excel<T = any>(aoas: T[][], config?: IExportConfig) {
const {
name = '导出',
sheetName = 'Sheet1',
bookType = 'xlsx',
merges,
colInfo,
rowInfo,
} = config || {}
const wb = XLSX.utils.book_new()
const ws = XLSX.utils.aoa_to_sheet(aoas)
if (merges) {
ws['!merges'] = merges
}
if (colInfo) {
ws['!cols'] = colInfo
}
if (rowInfo) {
ws['!rows'] = rowInfo
}
XLSX.utils.book_append_sheet(wb, ws, sheetName)
XLSX.writeFile(wb, `${name}.${bookType}`, { bookType })
}
/**
* @desc 从本地文件读取Excel工作簿
*
* 此函数从File或Blob对象读取Excel文件并返回工作簿对象
*
* @param {File | Blob} file - 要读取的Excel文件
* @returns {Promise<WorkBook | false>} 返回工作簿对象或false(读取失败时)
*/
function readWorkbookFromLocalFile(
file: File | Blob,
): Promise<WorkBook | false> {
return new Promise((resolve) => {
const reader = new FileReader()
reader.readAsBinaryString(file)
reader.onload = function (e) {
const data = (e.target as any)?.result
const workbook = XLSX.read(data, {
type: 'binary',
raw: true,
cellNF: true,
})
resolve(workbook)
}
reader.onerror = function () {
resolve(false)
}
})
}
/**
* @desc 从本地Excel文件读取数据为JSON格式
*
* 此函数从File或Blob对象读取Excel文件并返回第一个工作表的数据为JSON数组
*
* @param {File | Blob} file - 要读取的Excel文件
* @param {Sheet2JSONOpts} [options] - 工作表转JSON的选项
* @returns {Promise<any[] | false>} 返回JSON数组或false(读取失败时)
*/
function readFileToJson<T = any>(
file: File | Blob,
options?: Sheet2JSONOpts,
): Promise<T[] | false> {
return new Promise((resolve) => {
const reader = new FileReader()
reader.readAsBinaryString(file)
reader.onload = function (e) {
const data = (e.target as any)?.result
const workbook = XLSX.read(data, {
type: 'binary',
raw: true,
cellNF: true,
})
const json = XLSX.utils.sheet_to_json<T>(
workbook.Sheets[workbook.SheetNames[0]],
options,
)
resolve(json)
}
reader.onerror = function () {
resolve(false)
}
})
}
/**
* @desc 从本地Excel文件读取多个工作表的数据为JSON格式
*
* 此函数从File或Blob对象读取Excel文件并返回所有工作表的数据为JSON对象
*
* @param {File | Blob} file - 要读取的Excel文件
* @param {Sheet2JSONOpts} [options] - 工作表转JSON的选项
* @returns {Promise<Record<string, any[]> | false>} 返回包含所有工作表数据的对象或false(读取失败时)
*/
function readFileToJsons(
file: File | Blob,
options?: Sheet2JSONOpts,
): Promise<Record<string, any[]> | false> {
return new Promise((resolve) => {
const reader = new FileReader()
reader.readAsBinaryString(file)
reader.onload = function (e) {
const data = e.target?.result
const workbook = XLSX.read(data, {
type: 'binary',
raw: true,
cellNF: true,
})
const sheetNames = workbook.SheetNames
if (!sheetNames?.length) {
resolve(false)
}
const jsons = sheetNames.reduce(
(pre: Record<string, any[]>, cur: string) => {
const json = XLSX.utils.sheet_to_json(workbook.Sheets[cur], options)
pre[cur] = json
return pre
},
{},
)
resolve(jsons)
}
reader.onerror = function () {
resolve(false)
}
})
}
/**
* @desc 文件流导出Excel文件
*
* 此函数从File或Blob对象读取Excel文件流并导出为Excel文件
*
* @param {File | Blob} file - 要导出的Excel文件流
* @param {IExportConfig} config - 导出配置项
* @param {string} [config.name='导出'] - 导出文件名称
* @param {BookType} [config.bookType='xlsx'] - 导出文件类型
* @param {string} [config.errorMsg='下载失败'] - 错误提示信息
* @returns {Promise<void>}
*/
async function exportBuffer2Excel(file: File | Blob, config?: IExportConfig) {
const {
name = '导出',
bookType = 'xlsx',
errorMsg = '下载失败',
} = config || {}
const wb: WorkBook | false = await readWorkbookFromLocalFile(file)
if (wb) {
XLSX.writeFile(wb, `${name}.${bookType}`, { bookType })
} else {
message.error(errorMsg)
}
}
/**
* @desc 从URL导出Excel文件
*
* 此函数从URL获取Excel文件并导出
*
* @param {string} url - Excel文件的URL地址
* @param {IExportConfig} config - 导出配置项
* @param {string} [config.name='导出'] - 导出文件名称
* @param {BookType} [config.bookType='xlsx'] - 导出文件类型
* @param {string} [config.errorMsg='下载失败'] - 错误提示信息
* @returns {Promise<void>}
*/
async function exportUrl2Excel(url: string, config?: IExportConfig) {
fetch(url)
.then((response) => response.blob())
.then((blob) => {
exportBuffer2Excel(new Blob([blob]), config)
})
.catch((error) => {
throw error
})
}
/**
* @desc 从工作表中读取指定列的数据
*
* 此函数从Excel文件的指定工作表中读取指定列的数据
*
* @param {File | Blob} file - Excel文件
* @param {number} [sheetIndex=0] - 工作表索引
* @param {string[]} [columns=['A']] - 要读取的列数组(如['A', 'B'])
* @param {Record<string, string>} [fieldsMap={}] - 列名到字段名的映射
* @returns {Promise<any[] | false>} 返回包含指定列数据的数组或false(读取失败时)
*/
function readColumnFromSheet(
file: File | Blob,
sheetIndex: number = 0,
columns: string[] = ['A'],
fieldsMap: Record<string, string> = {},
): Promise<any[] | false> {
return new Promise((resolve) => {
const reader = new FileReader()
reader.readAsBinaryString(file)
reader.onload = function (e) {
const data = (e.target as any)?.result
const workbook = XLSX.read(data, {
type: 'binary',
raw: true,
cellNF: true,
})
const sheetName = workbook.SheetNames[sheetIndex]
const worksheet = workbook.Sheets[sheetName]
// 获取 A 列的所有数据,跳过第一行(标题行)
const columnData = []
const range = XLSX.utils.decode_range(worksheet['!ref'] as string)
// 从第2行开始(索引为1,跳过标题行)
for (let row = range.s.r + 1; row <= range.e.r; row++) {
const res: Record<string, any> = {}
columns.forEach((col: string) => {
const columnIndex = XLSX.utils.decode_col(col) // 将列字母转换为索引
const cellAddress = XLSX.utils.encode_cell({
r: row,
c: columnIndex,
}) // A列是第0列
const cell = worksheet[cellAddress]
const field = fieldsMap[col] ?? col
res[field] = cell ? cell.v : ''
})
columnData.push(res)
}
resolve(columnData)
}
reader.onerror = function () {
resolve(false)
}
})
}
/**
* @desc 从工作表中获取指定列的数据
*
* 此函数从Excel工作表中获取指定列的所有数据(跳过标题行)
*
* @param {XLSX.WorkSheet} worksheet - Excel工作表对象
* @param {string} column - 要获取数据的列(如'A'、'B')
* @returns {any[]} 返回指定列的数据数组
*/
function getColumnData(worksheet: XLSX.WorkSheet, column: string) {
const columnData = []
const range = XLSX.utils.decode_range(worksheet['!ref'] as string)
const columnIndex = XLSX.utils.decode_col(column) // 将列字母转换为索引
for (let row = range.s.r + 1; row <= range.e.r; row++) {
const cellAddress = XLSX.utils.encode_cell({ r: row, c: columnIndex })
const cell = worksheet[cellAddress]
columnData.push(cell ? cell.v : null)
}
return columnData
}
/**
* @desc 从本地文件读取Excel工作簿
*
* 此函数从File或Blob对象读取Excel文件并返回工作簿对象
*
* @param {File | Blob} file - 要读取的Excel文件
* @param {XLSX.ParsingOptions} [options] - 解析选项
* @returns {Promise<WorkBook | false>} 返回工作簿对象或false(读取失败时)
*/
function readWorkbookFromFile(
file: File | Blob,
options: XLSX.ParsingOptions = {
type: 'binary',
raw: true,
cellNF: true,
},
): Promise<WorkBook | false> {
return new Promise((resolve) => {
const reader = new FileReader()
reader.readAsBinaryString(file)
reader.onload = function (e) {
const data = (e.target as any)?.result
const workbook = XLSX.read(data, options)
resolve(workbook)
}
})
}
/**
* @desc 从URL读取Excel工作簿
*
* 此函数从URL读取Excel文件并返回工作簿对象
*
* @param {string} url - Excel文件的URL地址
* @param {XLSX.ParsingOptions} [options] - 解析选项
* @returns {WorkBook} 返回工作簿对象
*/
function readWorkbookFromUrl(
url: string,
options: XLSX.ParsingOptions = {
type: 'string',
raw: true,
cellNF: true,
},
): WorkBook {
const workbook = XLSX.readFile(url, options)
return workbook
}
/**
* @desc 从URL读取Excel工作簿
*
* 此函数从URL读取Excel文件并返回工作簿对象
*
* @param {string} url - Excel文件的URL地址
* @param {XLSX.ParsingOptions} [options] - 解析选项
* @returns {WorkBook} 返回工作簿对象
*/
async function readWorkbookFromUrl1(url: string): Promise<WorkBook | false> {
try {
const res = await fetch(url)
const blob = await res.blob()
const wb = readWorkbookFromFile(new Blob([blob]))
return Promise.resolve(wb)
} catch {
return Promise.resolve(false)
}
}
/**
* @desc 保存工作簿为Excel文件
*
* 此函数将工作簿对象保存为Excel文件
*
* @param {WorkBook} workbook - 要保存的工作簿对象
* @param {string} fileName - 文件名
* @param {XLSX.WritingOptions} [options] - 写入选项
* @returns {void}
*/
function saveWorkbook(
workbook: WorkBook,
fileName: string,
options?: XLSX.WritingOptions,
) {
XLSX.writeFile(workbook, fileName, options)
}
return {
exportJson2Excel,
exportAoa2Excel,
exportBuffer2Excel,
exportJson2ExcelSheets,
exportUrl2Excel,
readWorkbookFromLocalFile,
readFileToJson,
readFileToJsons,
readColumnFromSheet,
getColumnData,
readWorkbookFromFile,
readWorkbookFromUrl,
readWorkbookFromUrl1,
saveWorkbook,
}
}
export default useExcel
二、使用场景
以下使用示例都是基于上面的 useExcel
模拟的一条导出数据
const exportDatas = [
{
id: 6,
name: '假期/周末',
uniq_key: 2,
status: 1,
admin_name: '王光环',
last_update_time: 1733900693,
},
{
id: 52,
name: '12345678901234567890',
uniq_key: 32141,
status: 1,
admin_name: '王光环',
last_update_time: 1723458626,
},
{
id: 31,
name: '王林1',
uniq_key: 43,
status: 0,
admin_name: '王光环',
last_update_time: 1723458305,
},
{
id: 24,
name: '王林',
uniq_key: 44,
status: 0,
admin_name: '王光环',
last_update_time: 1723458246,
},
{
id: 50,
name: 'dsfgj',
uniq_key: 23,
status: 0,
admin_name: '朱宇航',
last_update_time: 1723457090,
},
{
id: 45,
name: '泥瓦工个',
uniq_key: 32,
status: 0,
admin_name: '王光环',
last_update_time: 1723451897,
},
{
id: 44,
name: '生产制造隔热',
uniq_key: 123421,
status: 0,
admin_name: '王光环',
last_update_time: 1723451890,
},
{
id: 42,
name: '哥人',
uniq_key: 121,
status: 0,
admin_name: '王光环',
last_update_time: 1723451876,
},
{
id: 40,
name: '亮反而',
uniq_key: 22,
status: 0,
admin_name: '王光环',
last_update_time: 1723451857,
},
{
id: 39,
name: '生产制造热',
uniq_key: 156,
status: 0,
admin_name: '王光环',
last_update_time: 1723451849,
},
{
id: 38,
name: 'v个人头',
uniq_key: 21,
status: 0,
admin_name: '王光环',
last_update_time: 1723451840,
},
{
id: 37,
name: '而非',
uniq_key: 1232,
status: 0,
admin_name: '王光环',
last_update_time: 1723451832,
},
{
id: 36,
name: '道路工/公路工/铁路工反而',
uniq_key: 12343,
status: 0,
admin_name: '王光环',
last_update_time: 1723451826,
},
{
id: 35,
name: '泥瓦工非',
uniq_key: 15,
status: 0,
admin_name: '王光环',
last_update_time: 1723451818,
},
{
id: 34,
name: '道路工/公路工/铁路工',
uniq_key: 14,
status: 0,
admin_name: '王光环',
last_update_time: 1723451811,
},
{
id: 33,
name: '淡而无味',
uniq_key: 11,
status: 0,
admin_name: '王光环',
last_update_time: 1723451802,
},
{
id: 4,
name: '一日一结',
uniq_key: 1,
status: 1,
admin_name: '王光环',
last_update_time: 1723449520,
},
{
id: 12,
name: '在线兼职',
uniq_key: 8,
status: 1,
admin_name: '朱宇航',
last_update_time: 1723445457,
},
{
id: 7,
name: '手艺活',
uniq_key: 3,
status: 1,
admin_name: '朱宇航',
last_update_time: 1723432946,
},
{
id: 10,
name: '在家兼职',
uniq_key: 6,
status: 1,
admin_name: '朱宇航',
last_update_time: 1723172619,
},
]
const headers = {
id: 'ID',
name: '链接名称',
uniq_key: '唯一标识',
status: '状态',
admin_name: '编辑人',
last_update_time: '最新编辑时间',
}
1、一维数组导出
/**
* @name: exportJson2ExcelHandler
* @description: 一维数组导出
*/
const exportJson2ExcelHandler = () => {
exportJson2Excel(exportDatas, {
headers,
name: '一维数组导出数据',
sheetName: '一维数组导出数据',
})
}
2、一维数组多sheet导出
/**
* @name: exportJson2ExcelSheetsHandler
* @description: 一维数组多Sheet导出
*/
const exportJson2ExcelSheetsHandler = () => {
const tip = `模板说明:\n
1、“企业id”填写说明:必填,需填写正确\n
2、“企业名称”填写说明:选填\n
3、“第三方平台”&“该企业的第三方id”填写说明:选填,目前第三方平台限填纷享销客`
const template = [
{
企业名称: null,
企业id: null,
第三方平台: null,
该企业的第三方id: null,
该企业的第三方名称: null,
模板说明: tip,
},
]
const merges = [{ s: { r: 1, c: 5 }, e: { r: 9, c: 5 } }]
const colInfo = [
{ width: 20 },
{ width: 40 },
{ width: 20 },
{ width: 20 },
{ width: 20 },
{ width: 40 },
]
exportJson2ExcelSheets({
name: '一维数组多Sheet导出数据',
sheets: [
{ json: template, sheetName: '模板', merges, colInfo },
{
headers,
json: exportDatas,
sheetName: '数据',
},
],
})
}
3、简单的模板下载
/**
* @name: downloadTemplate1
* @description: 简单的模板下载
*/
const downloadTemplate1 = async () => {
const name = '切词导入模板'
const sheetName = '导入模板'
const bookType = 'xlsx'
const merges = [{ s: { r: 1, c: 3 }, e: { r: 7, c: 3 } }]
const colInfo = [{ width: 20 }, { width: 20 }, { width: 20 }, { width: 50 }]
const tip = `1.“所属词包”填写说明:词包名称需与“词表词包管理”模块中的词包名称一致;\n
2. “状态”中,选项有待启用,已启用 \n(1)“待启用”状态的切词,将不被用户端取用 \n(2)“已启用”状态的切词,将被用户端取用`
const template = [
{
'切词(必填)': null,
'所属词包(选填)': null,
'状态(必填)': null,
模板使用说明: tip,
},
]
exportJson2Excel(template, { name, sheetName, merges, colInfo, bookType })
}
4、复杂的模板下载
// 工种没获取到的时候
const withoutWorksTemplate = () => {
const name = '搜索热词导入模板'
const sheetName = '导入模板'
const bookType = 'xlsx'
const merges = [{ s: { r: 1, c: 2 }, e: { r: 7, c: 2 } }]
const colInfo = [{ width: 20 }, { width: 20 }, { width: 40 }, { width: 30 }]
const tip = `1.“适用工种”填写说明:\n
(1)最右侧为最新的二级工种名称,请以此在“适用工种”中,录入正确的二级工种名称。\n
(2)录入多个工种时,需使用英文逗号隔开`
const template = [
{
'工种定向热词(必填)': '测试',
'适用工种(必填)': '二级工种1,二级工种2',
模板使用说明: tip,
},
]
exportJson2Excel(template, { name, sheetName, merges, colInfo, bookType })
}
/**
* @name: downloadTemplate
* @description: 复杂的模板下载
*/
const downloadTemplate = () => {
const name = '搜索热词导入模板'
const sheetName = '导入模板'
const bookType = 'xlsx'
const merges = [{ s: { r: 1, c: 2 }, e: { r: 7, c: 2 } }]
const colInfo = [{ width: 20 }, { width: 20 }, { width: 40 }, { width: 30 }]
const tip = `1.“适用工种”填写说明:\n
(1)最右侧为最新的二级工种名称,请以此在“适用工种”中,录入正确的二级工种名称。\n
(2)录入多个工种时,需使用英文逗号隔开`
toggleLoading()
getAllWorks({ level: 2, online: 1 })
.then((res) => {
const { code, result } = res || {}
if (code !== 0) return
if (isAvailableArr(result.list)) {
const header = [
'工种定向热词(必填)',
'适用工种(必填)',
'模板使用说明',
'最新二级工种列表',
]
const workNames = result.list.map((l: any) => l.name)
const contents = workNames.map((w: string, index: number) => {
if (index === 0) {
return ['测试', '二级工种1,二级工种2', tip, w]
}
return [null, null, null, w]
})
const template = [header, ...contents]
exportAoa2Excel(template, {
name,
sheetName,
merges,
colInfo,
bookType,
})
} else {
withoutWorksTemplate()
}
})
.catch(() => {
withoutWorksTemplate()
})
.finally(toggleLoading)
}
// getAllWorks为一个接口,不用在意,我们最终只是想取到里面的值而已,没有该接口我们也可以模拟一个对象数组 ,只需要里面有name属性就行
5、文件流导出
/**
* @name: exportCardData
* @description: 导出统计明细(文件流导出)
*/
const exportCardData = async () => {
toggleLoading()
try {
const res = await exportCardDatas({ pg: 1, pagesize: 100, export: 1 })
if (!res.code) {
exportBuffer2Excel(new Blob(['\ufeff', res as any]), {
name: '卡片统计明细',
bookType: 'xlsx',
})
} else {
message.error('导出统计明细失败')
}
} catch {
//
} finally {
toggleLoading()
}
}
// exportCardDatas是一个返回值为文件流的接口,可以自己模拟
6、文件地址下载
/**
* @name: downloadTempUrl
* @description: 文件地址下载(网络请求导出)
*/
const downloadTempUrl = () => {
const temp_url =
'https://jgj-store.oss-cn-beijing.aliyuncs.com/operation/manual_rule/demo.xlsx'
exportUrl2Excel(temp_url, { name: '手动触达推送人群导入模板' })
}
7、读取本地文件为json
function readFileToJson(
file: File | Blob,
): Promise<any | false> {
return new Promise((resolve) => {
const reader = new FileReader()
reader.readAsBinaryString(file)
reader.onload = function (e) {
const data = (e.target as any)?.result
const workbook = XLSX.read(data, {
type: 'binary',
raw: true,
cellNF: true,
})
const json = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]])
resolve(json)
}
reader.onerror = function () {
resolve(false)
}
})
}