-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
617 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export { default as ImportExcel } from './src/ImportExcel'; | ||
export { default as ExportExcelModel } from './src/ExportExcelModel.vue'; | ||
|
||
export { jsonToSheetXlsx, aoaToSheetXlsx } from './src/Export2Excel'; | ||
|
||
export * from './src/types'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import xlsx from 'xlsx'; | ||
import type { WorkBook } from 'xlsx'; | ||
import type { JsonToSheet, AoAToSheet } from './types'; | ||
// import { isObject } from '@/src/utils/is'; | ||
|
||
const { utils, writeFile } = xlsx; | ||
|
||
export function jsonToSheetXlsx<T = any>({ | ||
data, | ||
header, | ||
filename = 'excel-list.xlsx', | ||
json2sheetOpts = {}, | ||
write2excelOpts = { bookType: 'xlsx' }, | ||
}: JsonToSheet<T>) { | ||
const arrData = [...data]; | ||
if (header) { | ||
arrData.unshift(header); | ||
json2sheetOpts.skipHeader = true; | ||
} | ||
|
||
const worksheet = utils.json_to_sheet(arrData, json2sheetOpts); | ||
|
||
/* add worksheet to workbook */ | ||
const workbook: WorkBook = { | ||
SheetNames: [filename], | ||
Sheets: { | ||
[filename]: worksheet, | ||
}, | ||
}; | ||
/* output format determined by filename */ | ||
writeFile(workbook, filename, write2excelOpts); | ||
/* at this point, out.xlsb will have been downloaded */ | ||
} | ||
export function aoaToSheetXlsx<T = any>({ | ||
data, | ||
header, | ||
filename = 'excel-list.xlsx', | ||
write2excelOpts = { bookType: 'xlsx' }, | ||
}: AoAToSheet<T>) { | ||
const arrData = [...data]; | ||
if (header) { | ||
arrData.unshift(header); | ||
} | ||
|
||
const worksheet = utils.aoa_to_sheet(arrData); | ||
|
||
/* add worksheet to workbook */ | ||
const workbook: WorkBook = { | ||
SheetNames: [filename], | ||
Sheets: { | ||
[filename]: worksheet, | ||
}, | ||
}; | ||
/* output format determined by filename */ | ||
writeFile(workbook, filename, write2excelOpts); | ||
/* at this point, out.xlsb will have been downloaded */ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<template> | ||
<BasicModal v-bind="$attrs" title="导出数据" @ok="handleOk" @register="registerModal"> | ||
<BasicForm | ||
:labelWidth="100" | ||
:schemas="schemas" | ||
:showActionButtonGroup="false" | ||
@register="registerForm" | ||
/> | ||
</BasicModal> | ||
</template> | ||
<script lang="ts"> | ||
import { defineComponent } from 'vue'; | ||
import { BasicModal, useModalInner } from '/@/components/Modal'; | ||
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index'; | ||
const schemas: FormSchema[] = [ | ||
{ | ||
field: 'filename', | ||
component: 'Input', | ||
label: '文件名', | ||
rules: [{ required: true }], | ||
}, | ||
{ | ||
field: 'bookType', | ||
component: 'Select', | ||
label: '文件类型', | ||
defaultValue: 'xlsx', | ||
rules: [{ required: true }], | ||
componentProps: { | ||
options: [ | ||
{ | ||
label: 'xlsx', | ||
value: 'xlsx', | ||
key: 'xlsx', | ||
}, | ||
{ | ||
label: 'html', | ||
value: 'html', | ||
key: 'html', | ||
}, | ||
{ | ||
label: 'csv', | ||
value: 'csv', | ||
key: 'csv', | ||
}, | ||
{ | ||
label: 'txt', | ||
value: 'txt', | ||
key: 'txt', | ||
}, | ||
], | ||
}, | ||
}, | ||
]; | ||
export default defineComponent({ | ||
components: { BasicModal, BasicForm }, | ||
setup(_, { emit }) { | ||
const [registerForm, { validateFields }] = useForm(); | ||
const [registerModal, { closeModal }] = useModalInner(); | ||
async function handleOk() { | ||
const res = await validateFields(); | ||
const { filename, bookType } = res; | ||
emit('success', { | ||
filename: `${filename.split('.').shift()}.${bookType}`, | ||
bookType, | ||
}); | ||
closeModal(); | ||
} | ||
return { | ||
schemas, | ||
handleOk, | ||
registerForm, | ||
registerModal, | ||
}; | ||
}, | ||
}); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import { defineComponent, ref, unref } from 'vue'; | ||
import XLSX from 'xlsx'; | ||
import { getSlot } from '/@/utils/helper/tsxHelper'; | ||
|
||
import type { ExcelData } from './types'; | ||
export default defineComponent({ | ||
name: 'ImportExcel', | ||
setup(_, { slots, emit }) { | ||
const inputRef = ref<HTMLInputElement | null>(null); | ||
const loadingRef = ref<Boolean>(false); | ||
|
||
/** | ||
* @description: 第一行作为头部 | ||
*/ | ||
function getHeaderRow(sheet: XLSX.WorkSheet) { | ||
if (!sheet || !sheet['!ref']) return []; | ||
const headers: string[] = []; | ||
// A3:B7=>{s:{c:0, r:2}, e:{c:1, r:6}} | ||
const range = XLSX.utils.decode_range(sheet['!ref']); | ||
|
||
const R = range.s.r; | ||
/* start in the first row */ | ||
for (let C = range.s.c; C <= range.e.c; ++C) { | ||
/* walk every column in the range */ | ||
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]; | ||
/* find the cell in the first row */ | ||
let hdr = 'UNKNOWN ' + C; // <-- replace with your desired default | ||
if (cell && cell.t) hdr = XLSX.utils.format_cell(cell); | ||
headers.push(hdr); | ||
} | ||
return headers; | ||
} | ||
|
||
/** | ||
* @description: 获得excel数据 | ||
*/ | ||
function getExcelData(workbook: XLSX.WorkBook) { | ||
const excelData: ExcelData[] = []; | ||
for (const sheetName of workbook.SheetNames) { | ||
const worksheet = workbook.Sheets[sheetName]; | ||
const header: string[] = getHeaderRow(worksheet); | ||
const results = XLSX.utils.sheet_to_json(worksheet); | ||
excelData.push({ | ||
header, | ||
results, | ||
meta: { | ||
sheetName, | ||
}, | ||
}); | ||
} | ||
return excelData; | ||
} | ||
|
||
/** | ||
* @description: 读取excel数据 | ||
*/ | ||
function readerData(rawFile: File) { | ||
loadingRef.value = true; | ||
return new Promise((resolve, reject) => { | ||
const reader = new FileReader(); | ||
reader.onload = async (e) => { | ||
try { | ||
const data = e.target && e.target.result; | ||
const workbook = XLSX.read(data, { type: 'array' }); | ||
// console.log(workbook); | ||
/* DO SOMETHING WITH workbook HERE */ | ||
const excelData = getExcelData(workbook); | ||
emit('success', excelData); | ||
resolve(); | ||
} catch (error) { | ||
reject(error); | ||
} finally { | ||
loadingRef.value = false; | ||
} | ||
}; | ||
reader.readAsArrayBuffer(rawFile); | ||
}); | ||
} | ||
|
||
async function upload(rawFile: File) { | ||
const inputRefDom = unref(inputRef); | ||
if (inputRefDom) { | ||
// fix can't select the same excel | ||
inputRefDom.value = ''; | ||
} | ||
readerData(rawFile); | ||
} | ||
/** | ||
* @description: 触发选择文件管理器 | ||
*/ | ||
function handleInputClick(e: Event) { | ||
const files = e && (e.target as HTMLInputElement).files; | ||
const rawFile = files && files[0]; // only use files[0] | ||
if (!rawFile) return; | ||
upload(rawFile); | ||
} | ||
/** | ||
* @description: 点击上传按钮 | ||
*/ | ||
function handleUpload() { | ||
const inputRefDom = unref(inputRef); | ||
inputRefDom && inputRefDom.click(); | ||
} | ||
|
||
return () => { | ||
return ( | ||
<div> | ||
<input | ||
ref={inputRef} | ||
type="file" | ||
accept=".xlsx, .xls" | ||
style=" z-index: -9999; display: none;" | ||
onChange={handleInputClick} | ||
/> | ||
<div onClick={handleUpload}>{getSlot(slots)}</div> | ||
</div> | ||
); | ||
}; | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import type { JSON2SheetOpts, WritingOptions, BookType } from 'xlsx'; | ||
|
||
export interface ExcelData<T = any> { | ||
header: string[]; | ||
results: T[]; | ||
meta: { sheetName: string }; | ||
} | ||
|
||
// export interface ImportProps { | ||
// beforeUpload: (file: File) => boolean; | ||
// } | ||
|
||
export interface JsonToSheet<T = any> { | ||
data: T[]; | ||
header?: T; | ||
filename?: string; | ||
json2sheetOpts?: JSON2SheetOpts; | ||
write2excelOpts?: WritingOptions; | ||
} | ||
export interface AoAToSheet<T = any> { | ||
data: T[][]; | ||
header?: T[]; | ||
filename?: string; | ||
write2excelOpts?: WritingOptions; | ||
} | ||
|
||
export interface ExportModalResult { | ||
filename: string; | ||
bookType: BookType; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.