mirror of
https://gitee.com/bootx/dax-pay-ui.git
synced 2025-10-18 16:04:07 +00:00
ref 精简组件
This commit is contained in:
@@ -7,7 +7,7 @@ VITE_PUBLIC_PATH = /
|
|||||||
# Whether to enable gzip or brotli compression
|
# Whether to enable gzip or brotli compression
|
||||||
# Optional: gzip | brotli | none
|
# Optional: gzip | brotli | none
|
||||||
# If you need multiple forms, you can use `,` to separate
|
# If you need multiple forms, you can use `,` to separate
|
||||||
VITE_BUILD_COMPRESS = 'none'
|
VITE_BUILD_COMPRESS = 'gzip'
|
||||||
|
|
||||||
|
|
||||||
# Basic interface address SPA
|
# Basic interface address SPA
|
||||||
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -27,7 +27,6 @@
|
|||||||
"CHANGELOG.md": true,
|
"CHANGELOG.md": true,
|
||||||
"examples": true,
|
"examples": true,
|
||||||
"res": true,
|
"res": true,
|
||||||
"screenshots": true,
|
|
||||||
"yarn-error.log": true,
|
"yarn-error.log": true,
|
||||||
"**/.yarn": true
|
"**/.yarn": true
|
||||||
},
|
},
|
||||||
@@ -108,7 +107,6 @@
|
|||||||
"antv",
|
"antv",
|
||||||
"brotli",
|
"brotli",
|
||||||
"browserslist",
|
"browserslist",
|
||||||
"codemirror",
|
|
||||||
"commitlint",
|
"commitlint",
|
||||||
"cropperjs",
|
"cropperjs",
|
||||||
"echarts",
|
"echarts",
|
||||||
|
@@ -82,15 +82,12 @@
|
|||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"echarts": "^5.5.0",
|
"echarts": "^5.5.0",
|
||||||
"exceljs": "^4.4.0",
|
|
||||||
"html2canvas": "^1.4.1",
|
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"path-to-regexp": "^6.2.2",
|
"path-to-regexp": "^6.2.2",
|
||||||
"pinia": "2.1.7",
|
"pinia": "2.1.7",
|
||||||
"pinia-plugin-persistedstate": "^3.2.1",
|
"pinia-plugin-persistedstate": "^3.2.1",
|
||||||
"print-js": "^1.6.0",
|
|
||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
"qs": "^6.12.1",
|
"qs": "^6.12.1",
|
||||||
"resize-observer-polyfill": "^1.5.1",
|
"resize-observer-polyfill": "^1.5.1",
|
||||||
@@ -105,9 +102,7 @@
|
|||||||
"vue-types": "^5.1.1",
|
"vue-types": "^5.1.1",
|
||||||
"vuedraggable": "^4.1.0",
|
"vuedraggable": "^4.1.0",
|
||||||
"vxe-table": "^4.7.31",
|
"vxe-table": "^4.7.31",
|
||||||
"vxe-table-plugin-export-xlsx": "^4.0.2",
|
"xe-utils": "^3.5.25"
|
||||||
"xe-utils": "^3.5.25",
|
|
||||||
"xlsx": "^0.18.5"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^19.3.0",
|
"@commitlint/cli": "^19.3.0",
|
||||||
|
578
pnpm-lock.yaml
generated
578
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,8 +0,0 @@
|
|||||||
import { withInstall } from '@/utils';
|
|
||||||
import impExcel from './src/ImportExcel.vue';
|
|
||||||
import expExcelModal from './src/ExportExcelModal.vue';
|
|
||||||
|
|
||||||
export const ImpExcel = withInstall(impExcel);
|
|
||||||
export const ExpExcelModal = withInstall(expExcelModal);
|
|
||||||
export * from './src/typing';
|
|
||||||
export { jsonToSheetXlsx, aoaToSheetXlsx } from './src/Export2Excel';
|
|
@@ -1,148 +0,0 @@
|
|||||||
import * as xlsx from 'xlsx';
|
|
||||||
import type { WorkBook } from 'xlsx';
|
|
||||||
import type { JsonToSheet, AoAToSheet } from './typing';
|
|
||||||
import { AoaToMultipleSheet, JsonToMultipleSheet } from './typing';
|
|
||||||
|
|
||||||
const { utils, writeFile } = xlsx;
|
|
||||||
|
|
||||||
const DEF_FILE_NAME = 'excel-list.xlsx';
|
|
||||||
const DEF_SHEET_NAME = 'sheet';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param data source data
|
|
||||||
* @param worksheet worksheet object
|
|
||||||
* @param min min width
|
|
||||||
*/
|
|
||||||
function setColumnWidth(data, worksheet, min = 3) {
|
|
||||||
const obj = {};
|
|
||||||
worksheet['!cols'] = [];
|
|
||||||
data.forEach((item) => {
|
|
||||||
Object.keys(item).forEach((key) => {
|
|
||||||
const cur = item[key];
|
|
||||||
const length = cur?.length ?? min;
|
|
||||||
obj[key] = Math.max(length, obj[key] ?? min);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Object.keys(obj).forEach((key) => {
|
|
||||||
worksheet['!cols'].push({
|
|
||||||
wch: obj[key],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function jsonToSheetXlsx<T = any>({
|
|
||||||
data,
|
|
||||||
header,
|
|
||||||
filename = DEF_FILE_NAME,
|
|
||||||
sheetName = DEF_SHEET_NAME,
|
|
||||||
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);
|
|
||||||
setColumnWidth(arrData, worksheet);
|
|
||||||
/* add worksheet to workbook */
|
|
||||||
const workbook: WorkBook = {
|
|
||||||
SheetNames: [sheetName],
|
|
||||||
Sheets: {
|
|
||||||
[sheetName]: 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 = DEF_FILE_NAME,
|
|
||||||
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 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* json导出多Sheet的Xlsx
|
|
||||||
* @param sheetList 多sheet配置
|
|
||||||
* @param filename 文件名(包含后缀)
|
|
||||||
* @param write2excelOpts 文件配置
|
|
||||||
*/
|
|
||||||
export function jsonToMultipleSheetXlsx<T = any>({
|
|
||||||
sheetList,
|
|
||||||
filename = DEF_FILE_NAME,
|
|
||||||
write2excelOpts = { bookType: 'xlsx' },
|
|
||||||
}: JsonToMultipleSheet<T>) {
|
|
||||||
const workbook: WorkBook = {
|
|
||||||
SheetNames: [],
|
|
||||||
Sheets: {},
|
|
||||||
};
|
|
||||||
sheetList.forEach((p, index) => {
|
|
||||||
const arrData = [...p.data];
|
|
||||||
if (p.header) {
|
|
||||||
arrData.unshift(p.header);
|
|
||||||
p.json2sheetOpts = p.json2sheetOpts || {};
|
|
||||||
p.json2sheetOpts.skipHeader = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const worksheet = utils.json_to_sheet(arrData, p.json2sheetOpts);
|
|
||||||
setColumnWidth(arrData, worksheet);
|
|
||||||
|
|
||||||
p.sheetName = p.sheetName || `${DEF_SHEET_NAME}${index}`;
|
|
||||||
workbook.SheetNames.push(p.sheetName);
|
|
||||||
workbook.Sheets[p.sheetName] = worksheet;
|
|
||||||
});
|
|
||||||
writeFile(workbook, filename, write2excelOpts);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aoa导出多Sheet的Xlsx
|
|
||||||
* @param sheetList 多sheet配置
|
|
||||||
* @param filename 文件名(包含后缀)
|
|
||||||
* @param write2excelOpts 文件配置
|
|
||||||
*/
|
|
||||||
export function aoaToMultipleSheetXlsx<T = any>({
|
|
||||||
sheetList,
|
|
||||||
filename = DEF_FILE_NAME,
|
|
||||||
write2excelOpts = { bookType: 'xlsx' },
|
|
||||||
}: AoaToMultipleSheet<T>) {
|
|
||||||
const workbook: WorkBook = {
|
|
||||||
SheetNames: [],
|
|
||||||
Sheets: {},
|
|
||||||
};
|
|
||||||
sheetList.forEach((p, index) => {
|
|
||||||
const arrData = [...p.data];
|
|
||||||
if (p.header) {
|
|
||||||
arrData.unshift(p.header);
|
|
||||||
}
|
|
||||||
const worksheet = utils.aoa_to_sheet(arrData);
|
|
||||||
|
|
||||||
p.sheetName = p.sheetName || `${DEF_SHEET_NAME}${index}`;
|
|
||||||
workbook.SheetNames.push(p.sheetName);
|
|
||||||
workbook.Sheets[p.sheetName] = worksheet;
|
|
||||||
});
|
|
||||||
/* output format determined by filename */
|
|
||||||
writeFile(workbook, filename, write2excelOpts);
|
|
||||||
/* at this point, out.xlsb will have been downloaded */
|
|
||||||
}
|
|
@@ -1,79 +0,0 @@
|
|||||||
<template>
|
|
||||||
<BasicModal
|
|
||||||
v-bind="$attrs"
|
|
||||||
:title="t('component.excel.exportModalTitle')"
|
|
||||||
@ok="handleOk"
|
|
||||||
@register="registerModal"
|
|
||||||
>
|
|
||||||
<BasicForm
|
|
||||||
:labelWidth="100"
|
|
||||||
:schemas="schemas"
|
|
||||||
:showActionButtonGroup="false"
|
|
||||||
@register="registerForm"
|
|
||||||
/>
|
|
||||||
</BasicModal>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { ExportModalResult } from './typing';
|
|
||||||
import { BasicModal, useModalInner } from '@/components/Modal';
|
|
||||||
import { BasicForm, FormSchema, useForm } from '@/components/Form';
|
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/web/useI18n';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
const schemas: FormSchema[] = [
|
|
||||||
{
|
|
||||||
field: 'filename',
|
|
||||||
component: 'Input',
|
|
||||||
label: t('component.excel.fileName'),
|
|
||||||
rules: [{ required: true }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'bookType',
|
|
||||||
component: 'Select',
|
|
||||||
label: t('component.excel.fileType'),
|
|
||||||
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',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const emit = defineEmits(['success', 'register']);
|
|
||||||
|
|
||||||
const [registerForm, { validate }] = useForm();
|
|
||||||
const [registerModal, { closeModal }] = useModalInner();
|
|
||||||
|
|
||||||
const handleOk = async () => {
|
|
||||||
const res = await validate<ExportModalResult>();
|
|
||||||
const { filename, bookType } = res;
|
|
||||||
emit('success', {
|
|
||||||
filename: `${filename.split('.').shift()}.${bookType}`,
|
|
||||||
bookType,
|
|
||||||
});
|
|
||||||
closeModal();
|
|
||||||
};
|
|
||||||
</script>
|
|
@@ -1,221 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<input
|
|
||||||
ref="inputRef"
|
|
||||||
type="file"
|
|
||||||
v-show="false"
|
|
||||||
accept=".xlsx, .xls"
|
|
||||||
@change="handleInputClick"
|
|
||||||
/>
|
|
||||||
<div @click="handleUpload">
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, unref } from 'vue';
|
|
||||||
import * as XLSX from 'xlsx';
|
|
||||||
import { dateUtil } from '@/utils/dateUtil';
|
|
||||||
import type { ExcelData } from './typing';
|
|
||||||
|
|
||||||
defineOptions({ name: 'ImportExcel' });
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
// 日期时间格式。如果不提供或者提供空值,将返回原始Date对象
|
|
||||||
dateFormat: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
// 时区调整。实验性功能,仅为了解决读取日期时间值有偏差的问题。目前仅提供了+08:00时区的偏差修正值
|
|
||||||
// https://github.com/SheetJS/sheetjs/issues/1470#issuecomment-501108554
|
|
||||||
timeZone: {
|
|
||||||
type: Number,
|
|
||||||
default: 8,
|
|
||||||
},
|
|
||||||
// 是否直接返回选中文件
|
|
||||||
isReturnFile: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const emit = defineEmits(['success', 'error', 'cancel']);
|
|
||||||
|
|
||||||
const inputRef = ref<HTMLInputElement | null>(null);
|
|
||||||
const loadingRef = ref<Boolean>(false);
|
|
||||||
const cancelRef = ref<Boolean>(true);
|
|
||||||
|
|
||||||
function shapeWorkSheel(sheet: XLSX.WorkSheet, range: XLSX.Range) {
|
|
||||||
let str = ' ',
|
|
||||||
char = 65,
|
|
||||||
customWorkSheet = {
|
|
||||||
t: 's',
|
|
||||||
v: str,
|
|
||||||
r: '<t> </t><phoneticPr fontId="1" type="noConversion"/>',
|
|
||||||
h: str,
|
|
||||||
w: str,
|
|
||||||
};
|
|
||||||
if (!sheet || !sheet['!ref']) return [];
|
|
||||||
let c = 0,
|
|
||||||
r = 1;
|
|
||||||
while (c < range.e.c + 1) {
|
|
||||||
while (r < range.e.r + 1) {
|
|
||||||
if (!sheet[String.fromCharCode(char) + r]) {
|
|
||||||
sheet[String.fromCharCode(char) + r] = customWorkSheet;
|
|
||||||
}
|
|
||||||
r++;
|
|
||||||
}
|
|
||||||
r = 1;
|
|
||||||
str += ' ';
|
|
||||||
customWorkSheet = {
|
|
||||||
t: 's',
|
|
||||||
v: str,
|
|
||||||
r: '<t> </t><phoneticPr fontId="1" type="noConversion"/>',
|
|
||||||
h: str,
|
|
||||||
w: str,
|
|
||||||
};
|
|
||||||
c++;
|
|
||||||
char++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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.Range = XLSX.utils.decode_range(sheet['!ref']);
|
|
||||||
shapeWorkSheel(sheet, range);
|
|
||||||
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[] = [];
|
|
||||||
const { dateFormat, timeZone } = props;
|
|
||||||
for (const sheetName of workbook.SheetNames) {
|
|
||||||
const worksheet = workbook.Sheets[sheetName];
|
|
||||||
const header: string[] = getHeaderRow(worksheet);
|
|
||||||
let results = XLSX.utils.sheet_to_json(worksheet, {
|
|
||||||
raw: true,
|
|
||||||
dateNF: dateFormat, //Not worked
|
|
||||||
}) as object[];
|
|
||||||
results = results.map((row: object) => {
|
|
||||||
for (let field in row) {
|
|
||||||
if (row[field] instanceof Date) {
|
|
||||||
if (timeZone === 8) {
|
|
||||||
row[field].setSeconds(row[field].getSeconds() + 43);
|
|
||||||
}
|
|
||||||
if (dateFormat) {
|
|
||||||
row[field] = dateUtil(row[field]).format(dateFormat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return row;
|
|
||||||
});
|
|
||||||
|
|
||||||
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', cellDates: true });
|
|
||||||
// console.log(workbook);
|
|
||||||
/* DO SOMETHING WITH workbook HERE */
|
|
||||||
const excelData = getExcelData(workbook);
|
|
||||||
emit('success', excelData);
|
|
||||||
resolve('');
|
|
||||||
} catch (error) {
|
|
||||||
reject(error);
|
|
||||||
emit('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 = '';
|
|
||||||
}
|
|
||||||
await readerData(rawFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: 触发选择文件管理器
|
|
||||||
*/
|
|
||||||
function handleInputClick(e: Event) {
|
|
||||||
const target = e && (e.target as HTMLInputElement);
|
|
||||||
const files = target?.files;
|
|
||||||
const rawFile = files && files[0]; // only setting files[0]
|
|
||||||
|
|
||||||
target.value = '';
|
|
||||||
|
|
||||||
if (!rawFile) return;
|
|
||||||
|
|
||||||
cancelRef.value = false;
|
|
||||||
if (props.isReturnFile) {
|
|
||||||
emit('success', rawFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
upload(rawFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 文件选择器关闭后,判断取消状态
|
|
||||||
*/
|
|
||||||
function handleFocusChange() {
|
|
||||||
const timeId = setInterval(() => {
|
|
||||||
if (cancelRef.value === true) {
|
|
||||||
emit('cancel');
|
|
||||||
}
|
|
||||||
clearInterval(timeId);
|
|
||||||
window.removeEventListener('focus', handleFocusChange);
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: 点击上传按钮
|
|
||||||
*/
|
|
||||||
function handleUpload() {
|
|
||||||
const inputRefDom = unref(inputRef);
|
|
||||||
if (inputRefDom) {
|
|
||||||
cancelRef.value = true;
|
|
||||||
inputRefDom.click();
|
|
||||||
window.addEventListener('focus', handleFocusChange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
@@ -1,41 +0,0 @@
|
|||||||
import type { JSON2SheetOpts, WritingOptions, BookType } from 'xlsx';
|
|
||||||
|
|
||||||
export interface ExcelData<T = any> {
|
|
||||||
header: string[];
|
|
||||||
results: T[];
|
|
||||||
meta: { sheetName: string };
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface JsonToSheet<T = any> {
|
|
||||||
data: T[];
|
|
||||||
header?: T;
|
|
||||||
filename?: string;
|
|
||||||
sheetName?: string;
|
|
||||||
json2sheetOpts?: JSON2SheetOpts;
|
|
||||||
write2excelOpts?: WritingOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AoAToSheet<T = any> {
|
|
||||||
data: T[][];
|
|
||||||
header?: T[];
|
|
||||||
filename?: string;
|
|
||||||
sheetName?: string;
|
|
||||||
write2excelOpts?: WritingOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ExportModalResult {
|
|
||||||
filename: string;
|
|
||||||
bookType: BookType;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface JsonToMultipleSheet<T = any> {
|
|
||||||
sheetList: JsonToSheet<T>[];
|
|
||||||
filename?: string;
|
|
||||||
write2excelOpts?: WritingOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AoaToMultipleSheet<T = any> {
|
|
||||||
sheetList: AoAToSheet<T>[];
|
|
||||||
filename?: string;
|
|
||||||
write2excelOpts?: WritingOptions;
|
|
||||||
}
|
|
@@ -34,14 +34,10 @@ const DATE_TYPE = ['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker'];
|
|||||||
/**
|
/**
|
||||||
* 上传组件
|
* 上传组件
|
||||||
*/
|
*/
|
||||||
export const uploadItemType: ComponentType[] = [
|
export const uploadItemType: ComponentType[] = ['Upload', 'ImageUpload'];
|
||||||
'Upload',
|
|
||||||
'ImageUpload'
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
function genType() {
|
function genType() {
|
||||||
return [...DATE_TYPE, 'RangePicker',"TimeRangePicker"];
|
return [...DATE_TYPE, 'RangePicker', 'TimeRangePicker'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setComponentRuleType(
|
export function setComponentRuleType(
|
||||||
|
@@ -146,7 +146,7 @@ export function useFormEvents({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
validKeys.push(key);
|
validKeys.push(key);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
// Adapt common component
|
// Adapt common component
|
||||||
if (hasKey) {
|
if (hasKey) {
|
||||||
|
@@ -59,6 +59,7 @@
|
|||||||
import UploadPreviewModal from './components/UploadPreviewModal.vue';
|
import UploadPreviewModal from './components/UploadPreviewModal.vue';
|
||||||
import { BaseFileItem } from './types/typing';
|
import { BaseFileItem } from './types/typing';
|
||||||
import { buildUUID } from '@/utils/uuid';
|
import { buildUUID } from '@/utils/uuid';
|
||||||
|
|
||||||
defineOptions({ name: 'BasicUpload' });
|
defineOptions({ name: 'BasicUpload' });
|
||||||
|
|
||||||
const props = defineProps(uploadContainerProps);
|
const props = defineProps(uploadContainerProps);
|
||||||
@@ -86,9 +87,9 @@
|
|||||||
return omit(value, 'onChange');
|
return omit(value, 'onChange');
|
||||||
});
|
});
|
||||||
|
|
||||||
const isFirstRender = ref<boolean>(true)
|
const isFirstRender = ref<boolean>(true);
|
||||||
|
|
||||||
function getValue(valueKey="url") {
|
function getValue(valueKey = 'url') {
|
||||||
const list = (fileList.value || []).map((item: any) => {
|
const list = (fileList.value || []).map((item: any) => {
|
||||||
return item[valueKey];
|
return item[valueKey];
|
||||||
});
|
});
|
||||||
@@ -129,7 +130,7 @@
|
|||||||
emit('update:value', values);
|
emit('update:value', values);
|
||||||
if (!isFirstRender.value) {
|
if (!isFirstRender.value) {
|
||||||
emit('change', values);
|
emit('change', values);
|
||||||
isFirstRender.value = false
|
isFirstRender.value = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -63,7 +63,7 @@
|
|||||||
const fileList = ref<UploadProps['fileList']>([]);
|
const fileList = ref<UploadProps['fileList']>([]);
|
||||||
const isLtMsg = ref<boolean>(true);
|
const isLtMsg = ref<boolean>(true);
|
||||||
const isActMsg = ref<boolean>(true);
|
const isActMsg = ref<boolean>(true);
|
||||||
const isFirstRender = ref<boolean>(true)
|
const isFirstRender = ref<boolean>(true);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.value,
|
() => props.value,
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
emit('update:value', value);
|
emit('update:value', value);
|
||||||
if (!isFirstRender.value) {
|
if (!isFirstRender.value) {
|
||||||
emit('change', value);
|
emit('change', value);
|
||||||
isFirstRender.value = false
|
isFirstRender.value = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
import { BasicColumn } from '@/components/Table';
|
import { BasicColumn } from '@/components/Table';
|
||||||
import { useMessage } from '@/hooks/web/useMessage';
|
import { useMessage } from '@/hooks/web/useMessage';
|
||||||
import { buildUUID } from '@/utils/uuid';
|
import { buildUUID } from '@/utils/uuid';
|
||||||
|
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
|
|
||||||
const props = defineProps(previewProps);
|
const props = defineProps(previewProps);
|
||||||
|
@@ -14,7 +14,7 @@ type SortableOptions = Merge<
|
|||||||
// ...可扩展
|
// ...可扩展
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
export type handleFnKey = "record" | "valueKey" | "uidKey"
|
export type handleFnKey = 'record' | 'valueKey' | 'uidKey';
|
||||||
export type previewColumnsFnType = {
|
export type previewColumnsFnType = {
|
||||||
handleRemove: (record: Record<handleFnKey, any>) => any;
|
handleRemove: (record: Record<handleFnKey, any>) => any;
|
||||||
handleAdd: (record: Record<handleFnKey, any>) => any;
|
handleAdd: (record: Record<handleFnKey, any>) => any;
|
||||||
|
@@ -1,13 +1,7 @@
|
|||||||
import { withInstall } from '@/utils';
|
import { withInstall } from '@/utils';
|
||||||
import vxeBasicTable from './src/VxeBasicTable';
|
import vxeBasicTable from './src/VxeBasicTable';
|
||||||
import { VxeUI } from 'vxe-table';
|
|
||||||
import VXETablePluginAntd from './src/components';
|
|
||||||
import VXETablePluginExportXLSX from 'vxe-table-plugin-export-xlsx';
|
|
||||||
import ExcelJS from 'exceljs';
|
|
||||||
import './src/setting';
|
import './src/setting';
|
||||||
|
|
||||||
export const VxeBasicTable = withInstall(vxeBasicTable);
|
export const VxeBasicTable = withInstall(vxeBasicTable);
|
||||||
export * from 'vxe-table';
|
export * from 'vxe-table';
|
||||||
export * from './src/types';
|
export * from './src/types';
|
||||||
|
|
||||||
VxeUI.use(VXETablePluginAntd).use(VXETablePluginExportXLSX, { ExcelJS });
|
|
||||||
|
@@ -28,11 +28,6 @@
|
|||||||
"cancelText": "Close",
|
"cancelText": "Close",
|
||||||
"okText": "Confirm"
|
"okText": "Confirm"
|
||||||
},
|
},
|
||||||
"excel": {
|
|
||||||
"exportModalTitle": "Export data",
|
|
||||||
"fileType": "File type",
|
|
||||||
"fileName": "File name"
|
|
||||||
},
|
|
||||||
"form": {
|
"form": {
|
||||||
"putAway": "Put away",
|
"putAway": "Put away",
|
||||||
"unfold": "Unfold",
|
"unfold": "Unfold",
|
||||||
|
@@ -1,168 +0,0 @@
|
|||||||
{
|
|
||||||
"charts": {
|
|
||||||
"baiduMap": "Baidu map",
|
|
||||||
"aMap": "A map",
|
|
||||||
"googleMap": "Google map",
|
|
||||||
"charts": "Chart",
|
|
||||||
"map": "Map",
|
|
||||||
"line": "Line",
|
|
||||||
"pie": "Pie"
|
|
||||||
},
|
|
||||||
"comp": {
|
|
||||||
"comp": "Component",
|
|
||||||
"basic": "Basic",
|
|
||||||
"transition": "Animation",
|
|
||||||
"countTo": "Count To",
|
|
||||||
"scroll": "Scroll",
|
|
||||||
"scrollBasic": "Basic",
|
|
||||||
"scrollAction": "Scroll Function",
|
|
||||||
"virtualScroll": "Virtual Scroll",
|
|
||||||
"tree": "Tree",
|
|
||||||
"treeBasic": "Basic",
|
|
||||||
"editTree": "Searchable/toolbar",
|
|
||||||
"actionTree": "Function operation",
|
|
||||||
"modal": "Modal",
|
|
||||||
"drawer": "Drawer",
|
|
||||||
"desc": "Desc",
|
|
||||||
"verify": "Verify",
|
|
||||||
"verifyDrag": "Drag ",
|
|
||||||
"verifyRotate": "Picture Restore",
|
|
||||||
"qrcode": "QR code",
|
|
||||||
"strength": "Password strength",
|
|
||||||
"upload": "Upload",
|
|
||||||
"loading": "Loading",
|
|
||||||
"time": "Relative Time",
|
|
||||||
"cropperImage": "Cropper Image",
|
|
||||||
"cardList": "Card List"
|
|
||||||
},
|
|
||||||
"excel": {
|
|
||||||
"excel": "Excel",
|
|
||||||
"customExport": "Select export format",
|
|
||||||
"jsonExport": "JSON data export",
|
|
||||||
"arrayExport": "Array data export",
|
|
||||||
"importExcel": "Import"
|
|
||||||
},
|
|
||||||
"feat": {
|
|
||||||
"feat": "Page Function",
|
|
||||||
"icon": "Icon",
|
|
||||||
"screenShot": "Screen Shot",
|
|
||||||
"tabs": "Tabs",
|
|
||||||
"tabDetail": "Tab Detail",
|
|
||||||
"sessionTimeout": "Session Timeout",
|
|
||||||
"print": "Print",
|
|
||||||
"contextMenu": "Context Menu",
|
|
||||||
"download": "Download",
|
|
||||||
"clickOutSide": "ClickOutSide",
|
|
||||||
"imgPreview": "Picture Preview",
|
|
||||||
"copy": "Clipboard",
|
|
||||||
"ellipsis": "EllipsisText",
|
|
||||||
"msg": "Message prompt",
|
|
||||||
"watermark": "Watermark",
|
|
||||||
"ripple": "Ripple",
|
|
||||||
"fullScreen": "Full Screen",
|
|
||||||
"errorLog": "Error Log",
|
|
||||||
"tab": "Tab with parameters",
|
|
||||||
"tab1": "Tab with parameter 1",
|
|
||||||
"tab2": "Tab with parameter 2",
|
|
||||||
"menu": "Menu with parameters",
|
|
||||||
"menu1": "Menu with parameters 1",
|
|
||||||
"menu2": "Menu with parameters 2",
|
|
||||||
"ws": "Websocket test",
|
|
||||||
"breadcrumb": "Breadcrumbs",
|
|
||||||
"breadcrumbFlat": "Flat Mode",
|
|
||||||
"breadcrumbFlatDetail": "Flat mode details",
|
|
||||||
"requestDemo": "Retry request demo",
|
|
||||||
"breadcrumbChildren": "Level mode",
|
|
||||||
"breadcrumbChildrenDetail": "Level mode detail"
|
|
||||||
},
|
|
||||||
"form": {
|
|
||||||
"form": "Form",
|
|
||||||
"basic": "Basic",
|
|
||||||
"useForm": "useForm",
|
|
||||||
"refForm": "RefForm",
|
|
||||||
"advancedForm": "Shrinkable",
|
|
||||||
"ruleForm": "Form validation",
|
|
||||||
"dynamicForm": "Dynamic",
|
|
||||||
"customerForm": "Custom",
|
|
||||||
"appendForm": "Append",
|
|
||||||
"tabsForm": "TabsForm"
|
|
||||||
},
|
|
||||||
"iframe": {
|
|
||||||
"frame": "External",
|
|
||||||
"antv": "antVue doc (embedded)",
|
|
||||||
"doc": "Project doc (embedded)",
|
|
||||||
"docExternal": "Project doc (external)"
|
|
||||||
},
|
|
||||||
"level": {
|
|
||||||
"level": "MultiMenu"
|
|
||||||
},
|
|
||||||
"page": {
|
|
||||||
"page": "Page",
|
|
||||||
"form": "Form",
|
|
||||||
"formBasic": "Basic Form",
|
|
||||||
"formStep": "Step Form",
|
|
||||||
"formHigh": "Advanced Form",
|
|
||||||
"desc": "Details",
|
|
||||||
"descBasic": "Basic Details",
|
|
||||||
"descHigh": "Advanced Details",
|
|
||||||
"result": "Result",
|
|
||||||
"resultSuccess": "Success",
|
|
||||||
"resultFail": "Failed",
|
|
||||||
"account": "Personal",
|
|
||||||
"accountCenter": "Personal Center",
|
|
||||||
"accountSetting": "Personal Settings",
|
|
||||||
"exception": "Exception",
|
|
||||||
"netWorkError": "Network Error",
|
|
||||||
"notData": "No data",
|
|
||||||
"list": "List page",
|
|
||||||
"listCard": "Card list",
|
|
||||||
"basic": "Basic list",
|
|
||||||
"listBasic": "Basic list",
|
|
||||||
"listSearch": "Search list"
|
|
||||||
},
|
|
||||||
"permission": {
|
|
||||||
"permission": "Permission",
|
|
||||||
"front": "front-end",
|
|
||||||
"frontPage": "Page",
|
|
||||||
"frontBtn": "Button",
|
|
||||||
"frontTestA": "Test page A",
|
|
||||||
"frontTestB": "Test page B",
|
|
||||||
"back": "background",
|
|
||||||
"backPage": "Page",
|
|
||||||
"backBtn": "Button"
|
|
||||||
},
|
|
||||||
"steps": {
|
|
||||||
"page": "Intro page"
|
|
||||||
},
|
|
||||||
"system": {
|
|
||||||
"moduleName": "System management",
|
|
||||||
"account": "Account management",
|
|
||||||
"vxeTableAccount": "Account management(VxeTable)",
|
|
||||||
"account_detail": "Account detail",
|
|
||||||
"password": "Change password",
|
|
||||||
"dept": "Department management",
|
|
||||||
"menu": "Menu management",
|
|
||||||
"role": "Role management"
|
|
||||||
},
|
|
||||||
"table": {
|
|
||||||
"table": "Table",
|
|
||||||
"basic": "Basic",
|
|
||||||
"treeTable": "Tree",
|
|
||||||
"fetchTable": "Remote loading",
|
|
||||||
"fixedColumn": "Fixed column",
|
|
||||||
"customerCell": "Custom column",
|
|
||||||
"formTable": "Open search",
|
|
||||||
"useTable": "UseTable",
|
|
||||||
"refTable": "RefTable",
|
|
||||||
"multipleHeader": "MultiLevel header",
|
|
||||||
"mergeHeader": "Merge cells",
|
|
||||||
"expandTable": "Expandable table",
|
|
||||||
"fixedHeight": "Fixed height",
|
|
||||||
"footerTable": "Footer",
|
|
||||||
"editCellTable": "Editable cell",
|
|
||||||
"editRowTable": "Editable row",
|
|
||||||
"authColumn": "Auth column",
|
|
||||||
"resizeParentHeightTable": "resizeParentHeightTable",
|
|
||||||
"vxeTable": "VxeTable"
|
|
||||||
}
|
|
||||||
}
|
|
@@ -28,11 +28,6 @@
|
|||||||
"cancelText": "关闭",
|
"cancelText": "关闭",
|
||||||
"okText": "确认"
|
"okText": "确认"
|
||||||
},
|
},
|
||||||
"excel": {
|
|
||||||
"exportModalTitle": "导出数据",
|
|
||||||
"fileType": "文件类型",
|
|
||||||
"fileName": "文件名"
|
|
||||||
},
|
|
||||||
"form": {
|
"form": {
|
||||||
"putAway": "收起",
|
"putAway": "收起",
|
||||||
"unfold": "展开",
|
"unfold": "展开",
|
||||||
|
@@ -35,17 +35,9 @@
|
|||||||
"cropperImage": "图片裁剪",
|
"cropperImage": "图片裁剪",
|
||||||
"cardList": "卡片列表"
|
"cardList": "卡片列表"
|
||||||
},
|
},
|
||||||
"excel": {
|
|
||||||
"excel": "Excel",
|
|
||||||
"customExport": "选择导出格式",
|
|
||||||
"jsonExport": "JSON数据导出",
|
|
||||||
"arrayExport": "Array数据导出",
|
|
||||||
"importExcel": "导入"
|
|
||||||
},
|
|
||||||
"feat": {
|
"feat": {
|
||||||
"feat": "功能",
|
"feat": "功能",
|
||||||
"icon": "图标",
|
"icon": "图标",
|
||||||
"screenShot": "截图",
|
|
||||||
"sessionTimeout": "登录过期",
|
"sessionTimeout": "登录过期",
|
||||||
"tabs": "标签页操作",
|
"tabs": "标签页操作",
|
||||||
"tabDetail": "标签详情页",
|
"tabDetail": "标签详情页",
|
||||||
|
@@ -23,14 +23,6 @@ const feat: AppRouteModule = {
|
|||||||
title: t('routes.demo.feat.icon'),
|
title: t('routes.demo.feat.icon'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'screenshot',
|
|
||||||
name: 'Screenshot',
|
|
||||||
component: () => import('@/views/demo/feat/screenshot/index.vue'),
|
|
||||||
meta: {
|
|
||||||
title: t('routes.demo.feat.screenShot'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'ws',
|
path: 'ws',
|
||||||
name: 'WebSocket',
|
name: 'WebSocket',
|
||||||
@@ -56,14 +48,6 @@ const feat: AppRouteModule = {
|
|||||||
title: t('routes.demo.feat.sessionTimeout'),
|
title: t('routes.demo.feat.sessionTimeout'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'print',
|
|
||||||
name: 'Print',
|
|
||||||
component: () => import('@/views/demo/feat/print/index.vue'),
|
|
||||||
meta: {
|
|
||||||
title: t('routes.demo.feat.print'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'tabs',
|
path: 'tabs',
|
||||||
name: 'TabsDemo',
|
name: 'TabsDemo',
|
||||||
@@ -228,51 +212,6 @@ const feat: AppRouteModule = {
|
|||||||
title: t('routes.demo.feat.errorLog'),
|
title: t('routes.demo.feat.errorLog'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'excel',
|
|
||||||
name: 'Excel',
|
|
||||||
redirect: '/feat/excel/customExport',
|
|
||||||
component: getParentLayout('Excel'),
|
|
||||||
meta: {
|
|
||||||
// icon: 'mdi:microsoft-excel',
|
|
||||||
title: t('routes.demo.excel.excel'),
|
|
||||||
},
|
|
||||||
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'customExport',
|
|
||||||
name: 'CustomExport',
|
|
||||||
component: () => import('@/views/demo/excel/CustomExport.vue'),
|
|
||||||
meta: {
|
|
||||||
title: t('routes.demo.excel.customExport'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'jsonExport',
|
|
||||||
name: 'JsonExport',
|
|
||||||
component: () => import('@/views/demo/excel/JsonExport.vue'),
|
|
||||||
meta: {
|
|
||||||
title: t('routes.demo.excel.jsonExport'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'arrayExport',
|
|
||||||
name: 'ArrayExport',
|
|
||||||
component: () => import('@/views/demo/excel/ArrayExport.vue'),
|
|
||||||
meta: {
|
|
||||||
title: t('routes.demo.excel.arrayExport'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'importExcel',
|
|
||||||
name: 'ImportExcel',
|
|
||||||
component: () => import('@/views/demo/excel/ImportExcel.vue'),
|
|
||||||
meta: {
|
|
||||||
title: t('routes.demo.excel.importExcel'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'testTab/:id',
|
path: 'testTab/:id',
|
||||||
name: 'TestTab',
|
name: 'TestTab',
|
||||||
|
@@ -169,7 +169,7 @@ const setting: ProjectConfig = {
|
|||||||
showBreadCrumbIcon: false,
|
showBreadCrumbIcon: false,
|
||||||
|
|
||||||
// Use error-handler-plugin
|
// Use error-handler-plugin
|
||||||
useErrorHandle: false,
|
useErrorHandle: true,
|
||||||
|
|
||||||
// Whether to open back to top
|
// Whether to open back to top
|
||||||
useOpenBackTop: true,
|
useOpenBackTop: true,
|
||||||
|
@@ -1,45 +0,0 @@
|
|||||||
<template>
|
|
||||||
<PageWrapper title="导出示例" content="根据数组格式的数据进行导出">
|
|
||||||
<BasicTable title="基础表格" :columns="columns" :dataSource="data">
|
|
||||||
<template #toolbar>
|
|
||||||
<a-button @click="aoaToExcel"> 导出 </a-button>
|
|
||||||
<a-button @click="aoaToMultipleSheet" danger> 导出多Sheet </a-button>
|
|
||||||
</template>
|
|
||||||
</BasicTable>
|
|
||||||
</PageWrapper>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { BasicTable } from '@/components/Table';
|
|
||||||
import { aoaToSheetXlsx } from '@/components/Excel';
|
|
||||||
import { arrHeader, arrData, columns, data } from './data';
|
|
||||||
import { PageWrapper } from '@/components/Page';
|
|
||||||
import { aoaToMultipleSheetXlsx } from '@/components/Excel/src/Export2Excel';
|
|
||||||
|
|
||||||
function aoaToExcel() {
|
|
||||||
// 保证data顺序与header一致
|
|
||||||
aoaToSheetXlsx({
|
|
||||||
data: arrData,
|
|
||||||
header: arrHeader,
|
|
||||||
filename: '二维数组方式导出excel.xlsx',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function aoaToMultipleSheet() {
|
|
||||||
// 保证data顺序与header一致
|
|
||||||
aoaToMultipleSheetXlsx({
|
|
||||||
sheetList: [
|
|
||||||
{
|
|
||||||
data: arrData,
|
|
||||||
header: arrHeader,
|
|
||||||
sheetName: 'Sheet1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: arrData,
|
|
||||||
header: arrHeader,
|
|
||||||
sheetName: 'Sheet2',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
filename: '二维数组方式导出excel-多Sheet示例.xlsx',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
@@ -1,30 +0,0 @@
|
|||||||
<template>
|
|
||||||
<PageWrapper title="导出示例" content="可以选择导出格式">
|
|
||||||
<BasicTable title="基础表格" :columns="columns" :dataSource="data">
|
|
||||||
<template #toolbar>
|
|
||||||
<a-button @click="openModal"> 导出 </a-button>
|
|
||||||
</template>
|
|
||||||
</BasicTable>
|
|
||||||
<ExpExcelModal @register="register" @success="defaultHeader" />
|
|
||||||
</PageWrapper>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { BasicTable } from '@/components/Table';
|
|
||||||
import { jsonToSheetXlsx, ExpExcelModal, ExportModalResult } from '@/components/Excel';
|
|
||||||
import { columns, data } from './data';
|
|
||||||
import { useModal } from '@/components/Modal';
|
|
||||||
import { PageWrapper } from '@/components/Page';
|
|
||||||
|
|
||||||
function defaultHeader({ filename, bookType }: ExportModalResult) {
|
|
||||||
// 默认Object.keys(data[0])作为header
|
|
||||||
jsonToSheetXlsx({
|
|
||||||
data,
|
|
||||||
filename,
|
|
||||||
write2excelOpts: {
|
|
||||||
bookType,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const [register, { openModal }] = useModal();
|
|
||||||
</script>
|
|
@@ -1,46 +0,0 @@
|
|||||||
<template>
|
|
||||||
<PageWrapper title="excel数据导入示例">
|
|
||||||
<ImpExcel @success="loadDataSuccess" dateFormat="YYYY-MM-DD">
|
|
||||||
<a-button class="m-3"> 导入Excel </a-button>
|
|
||||||
</ImpExcel>
|
|
||||||
<BasicTable
|
|
||||||
v-for="(table, index) in tableListRef"
|
|
||||||
:key="index"
|
|
||||||
:title="table.title"
|
|
||||||
:columns="table.columns"
|
|
||||||
:dataSource="table.dataSource"
|
|
||||||
/>
|
|
||||||
</PageWrapper>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref } from 'vue';
|
|
||||||
|
|
||||||
import { ImpExcel, ExcelData } from '@/components/Excel';
|
|
||||||
import { BasicTable, BasicColumn } from '@/components/Table';
|
|
||||||
import { PageWrapper } from '@/components/Page';
|
|
||||||
|
|
||||||
const tableListRef = ref<
|
|
||||||
{
|
|
||||||
title: string;
|
|
||||||
columns?: any[];
|
|
||||||
dataSource?: any[];
|
|
||||||
}[]
|
|
||||||
>([]);
|
|
||||||
|
|
||||||
function loadDataSuccess(excelDataList: ExcelData[]) {
|
|
||||||
tableListRef.value = [];
|
|
||||||
console.log(excelDataList);
|
|
||||||
for (const excelData of excelDataList) {
|
|
||||||
const {
|
|
||||||
header,
|
|
||||||
results,
|
|
||||||
meta: { sheetName },
|
|
||||||
} = excelData;
|
|
||||||
const columns: BasicColumn[] = [];
|
|
||||||
for (const title of header) {
|
|
||||||
columns.push({ title, dataIndex: title });
|
|
||||||
}
|
|
||||||
tableListRef.value.push({ title: sheetName, dataSource: results, columns });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
@@ -1,76 +0,0 @@
|
|||||||
<template>
|
|
||||||
<PageWrapper title="导出示例" content="根据JSON格式的数据进行导出">
|
|
||||||
<BasicTable title="基础表格" :columns="columns" :dataSource="data">
|
|
||||||
<template #toolbar>
|
|
||||||
<a-button @click="defaultHeader"> 导出:默认头部 </a-button>
|
|
||||||
<a-button @click="customHeader"> 导出:自定义头部 </a-button>
|
|
||||||
<a-button @click="handleMultipleSheet" danger> 导出多Sheet </a-button>
|
|
||||||
</template>
|
|
||||||
</BasicTable>
|
|
||||||
</PageWrapper>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { BasicTable } from '@/components/Table';
|
|
||||||
import { jsonToSheetXlsx } from '@/components/Excel';
|
|
||||||
import { columns, data } from './data';
|
|
||||||
import { PageWrapper } from '@/components/Page';
|
|
||||||
import { jsonToMultipleSheetXlsx } from '@/components/Excel/src/Export2Excel';
|
|
||||||
|
|
||||||
function defaultHeader() {
|
|
||||||
// 默认Object.keys(data[0])作为header
|
|
||||||
jsonToSheetXlsx({
|
|
||||||
data,
|
|
||||||
filename: '使用key作为默认头部.xlsx',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function customHeader() {
|
|
||||||
jsonToSheetXlsx({
|
|
||||||
data,
|
|
||||||
header: {
|
|
||||||
id: 'ID',
|
|
||||||
name: '姓名',
|
|
||||||
age: '年龄',
|
|
||||||
no: '编号',
|
|
||||||
address: '地址',
|
|
||||||
beginTime: '开始时间',
|
|
||||||
endTime: '结束时间',
|
|
||||||
},
|
|
||||||
filename: '自定义头部.xlsx',
|
|
||||||
json2sheetOpts: {
|
|
||||||
// 指定顺序
|
|
||||||
header: ['name', 'id'],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleMultipleSheet() {
|
|
||||||
jsonToMultipleSheetXlsx({
|
|
||||||
sheetList: [
|
|
||||||
{
|
|
||||||
data,
|
|
||||||
sheetName: '使用key作为默认头部',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data,
|
|
||||||
header: {
|
|
||||||
id: 'ID',
|
|
||||||
name: '姓名',
|
|
||||||
age: '年龄',
|
|
||||||
no: '编号',
|
|
||||||
address: '地址',
|
|
||||||
beginTime: '开始时间',
|
|
||||||
endTime: '结束时间',
|
|
||||||
},
|
|
||||||
json2sheetOpts: {
|
|
||||||
// 指定顺序
|
|
||||||
header: ['name', 'id'],
|
|
||||||
},
|
|
||||||
sheetName: '自定义头部',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
filename: '多Sheet导出示例.xlsx',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
@@ -1,59 +0,0 @@
|
|||||||
import { BasicColumn } from '@/components/Table';
|
|
||||||
|
|
||||||
export const columns: BasicColumn[] = [
|
|
||||||
{
|
|
||||||
title: 'ID',
|
|
||||||
dataIndex: 'id',
|
|
||||||
width: 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '姓名',
|
|
||||||
dataIndex: 'name',
|
|
||||||
width: 120,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '年龄',
|
|
||||||
dataIndex: 'age',
|
|
||||||
width: 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '编号',
|
|
||||||
dataIndex: 'no',
|
|
||||||
width: 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '地址',
|
|
||||||
dataIndex: 'address',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '开始时间',
|
|
||||||
dataIndex: 'beginTime',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '结束时间',
|
|
||||||
dataIndex: 'endTime',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const data: any[] = (() => {
|
|
||||||
const arr: any[] = [];
|
|
||||||
for (let index = 0; index < 40; index++) {
|
|
||||||
arr.push({
|
|
||||||
id: `${index}`,
|
|
||||||
name: `${index} John Brown`,
|
|
||||||
age: `${index + 10}`,
|
|
||||||
no: `${index}98678`,
|
|
||||||
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
|
|
||||||
beginTime: new Date().toLocaleString(),
|
|
||||||
endTime: new Date().toLocaleString(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
})();
|
|
||||||
|
|
||||||
// ["ID", "姓名", "年龄", "编号", "地址", "开始时间", "结束时间"]
|
|
||||||
export const arrHeader = columns.map((column) => column.title);
|
|
||||||
// [["ID", "姓名", "年龄", "编号", "地址", "开始时间", "结束时间"],["0", "0 John Brown", "10", "098678"]]
|
|
||||||
export const arrData = data.map((item) => {
|
|
||||||
return Object.keys(item).map((key) => item[key]);
|
|
||||||
});
|
|
@@ -1,40 +0,0 @@
|
|||||||
<template>
|
|
||||||
<PageWrapper title="打印示例">
|
|
||||||
<CollapseContainer title="json打印表格">
|
|
||||||
<a-button type="primary" @click="jsonPrint">打印</a-button>
|
|
||||||
</CollapseContainer>
|
|
||||||
|
|
||||||
<a-button type="primary" class="mt-5" @click="imagePrint">Image Print</a-button>
|
|
||||||
</PageWrapper>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { PageWrapper } from '@/components/Page';
|
|
||||||
import { CollapseContainer } from '@/components/Container';
|
|
||||||
|
|
||||||
import printJS from 'print-js';
|
|
||||||
|
|
||||||
defineOptions({ name: 'AppLogo' });
|
|
||||||
|
|
||||||
function jsonPrint() {
|
|
||||||
printJS({
|
|
||||||
printable: [
|
|
||||||
{ name: 'll', email: '123@gmail.com', phone: '123' },
|
|
||||||
{ name: 'qq', email: '456@gmail.com', phone: '456' },
|
|
||||||
],
|
|
||||||
properties: ['name', 'email', 'phone'],
|
|
||||||
type: 'json',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function imagePrint() {
|
|
||||||
printJS({
|
|
||||||
printable: [
|
|
||||||
'https://anncwb.github.io/anncwb/images/preview1.png',
|
|
||||||
'https://anncwb.github.io/anncwb/images/preview2.png',
|
|
||||||
],
|
|
||||||
type: 'image',
|
|
||||||
header: 'Multiple Images',
|
|
||||||
imageStyle: 'width:100%;',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
@@ -1,77 +0,0 @@
|
|||||||
<template>
|
|
||||||
<PageWrapper title="截图示例">
|
|
||||||
<CollapseContainer title="截图操作">
|
|
||||||
<a-button type="primary" class="mr-2" @click="handleScreenshot">截取当前body</a-button>
|
|
||||||
<a-button type="primary" class="mr-2" :disabled="!showPicture" @click="handleDelScreenshot"
|
|
||||||
>删除截图</a-button
|
|
||||||
>
|
|
||||||
<a-button type="primary" class="mr-2" :disabled="!showPicture" @click="handlePrintScreenshot"
|
|
||||||
>打印截图</a-button
|
|
||||||
>
|
|
||||||
<a-button
|
|
||||||
type="primary"
|
|
||||||
class="mr-2"
|
|
||||||
:disabled="!showPicture"
|
|
||||||
@click="handleDownloadScreenshot"
|
|
||||||
>下载截图</a-button
|
|
||||||
>
|
|
||||||
</CollapseContainer>
|
|
||||||
|
|
||||||
<Card title="截图内容" class="mt-4">
|
|
||||||
<div ref="pictureRef" v-show="showPicture"></div>
|
|
||||||
</Card>
|
|
||||||
</PageWrapper>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { PageWrapper } from '@/components/Page';
|
|
||||||
import html2canvas from 'html2canvas';
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { Card } from 'ant-design-vue';
|
|
||||||
import { CollapseContainer } from '@/components/Container';
|
|
||||||
import printJS from 'print-js';
|
|
||||||
import { downloadByBase64 } from '@/utils/file/download';
|
|
||||||
|
|
||||||
const pictureRef = ref();
|
|
||||||
const showPicture = ref<boolean>(false);
|
|
||||||
const canvasUrl = ref<string>('');
|
|
||||||
|
|
||||||
function handleScreenshot() {
|
|
||||||
if (showPicture.value) return;
|
|
||||||
html2canvas(document.body, {
|
|
||||||
backgroundColor: '#ffffff',
|
|
||||||
allowTaint: true, //开启跨域
|
|
||||||
useCORS: true,
|
|
||||||
scrollY: 0,
|
|
||||||
scrollX: 0,
|
|
||||||
})
|
|
||||||
.then(function (canvas) {
|
|
||||||
canvas.style.width = '100%';
|
|
||||||
canvas.style.height = '100%';
|
|
||||||
pictureRef.value.appendChild(canvas);
|
|
||||||
showPicture.value = true;
|
|
||||||
canvasUrl.value = canvas.toDataURL();
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log('绘制失败', err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleDelScreenshot() {
|
|
||||||
pictureRef.value.innerHTML = '';
|
|
||||||
canvasUrl.value = '';
|
|
||||||
showPicture.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handlePrintScreenshot() {
|
|
||||||
if (!canvasUrl.value) return;
|
|
||||||
printJS({
|
|
||||||
printable: canvasUrl.value,
|
|
||||||
type: 'image',
|
|
||||||
base64: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleDownloadScreenshot() {
|
|
||||||
downloadByBase64(canvasUrl.value, 'screen_shot.png');
|
|
||||||
}
|
|
||||||
</script>
|
|
Reference in New Issue
Block a user