mirror of
https://gitee.com/bootx/dax-pay-ui.git
synced 2025-10-15 06:39:02 +00:00
ref 精简组件
This commit is contained in:
@@ -7,7 +7,7 @@ VITE_PUBLIC_PATH = /
|
||||
# Whether to enable gzip or brotli compression
|
||||
# Optional: gzip | brotli | none
|
||||
# If you need multiple forms, you can use `,` to separate
|
||||
VITE_BUILD_COMPRESS = 'none'
|
||||
VITE_BUILD_COMPRESS = 'gzip'
|
||||
|
||||
|
||||
# Basic interface address SPA
|
||||
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -27,7 +27,6 @@
|
||||
"CHANGELOG.md": true,
|
||||
"examples": true,
|
||||
"res": true,
|
||||
"screenshots": true,
|
||||
"yarn-error.log": true,
|
||||
"**/.yarn": true
|
||||
},
|
||||
@@ -108,7 +107,6 @@
|
||||
"antv",
|
||||
"brotli",
|
||||
"browserslist",
|
||||
"codemirror",
|
||||
"commitlint",
|
||||
"cropperjs",
|
||||
"echarts",
|
||||
|
@@ -82,15 +82,12 @@
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"echarts": "^5.5.0",
|
||||
"exceljs": "^4.4.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mockjs": "^1.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"path-to-regexp": "^6.2.2",
|
||||
"pinia": "2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"print-js": "^1.6.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"qs": "^6.12.1",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
@@ -105,9 +102,7 @@
|
||||
"vue-types": "^5.1.1",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"vxe-table": "^4.7.31",
|
||||
"vxe-table-plugin-export-xlsx": "^4.0.2",
|
||||
"xe-utils": "^3.5.25",
|
||||
"xlsx": "^0.18.5"
|
||||
"xe-utils": "^3.5.25"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@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;
|
||||
}
|
@@ -287,11 +287,11 @@
|
||||
const on = {
|
||||
[eventKey]: (...args: Nullable<Recordable<any>>[]) => {
|
||||
const [e] = args;
|
||||
|
||||
|
||||
const target = e ? e.target : null;
|
||||
let value = target ? (isCheck ? target.checked : target.value) : e;
|
||||
if(isFunction(valueFormat)){
|
||||
value = valueFormat({...unref(getValues),value});
|
||||
if (isFunction(valueFormat)) {
|
||||
value = valueFormat({ ...unref(getValues), value });
|
||||
}
|
||||
props.setFormModel(field, value, props.schema);
|
||||
|
||||
|
@@ -34,14 +34,10 @@ const DATE_TYPE = ['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker'];
|
||||
/**
|
||||
* 上传组件
|
||||
*/
|
||||
export const uploadItemType: ComponentType[] = [
|
||||
'Upload',
|
||||
'ImageUpload'
|
||||
];
|
||||
|
||||
export const uploadItemType: ComponentType[] = ['Upload', 'ImageUpload'];
|
||||
|
||||
function genType() {
|
||||
return [...DATE_TYPE, 'RangePicker',"TimeRangePicker"];
|
||||
return [...DATE_TYPE, 'RangePicker', 'TimeRangePicker'];
|
||||
}
|
||||
|
||||
export function setComponentRuleType(
|
||||
|
@@ -25,12 +25,12 @@ interface UseFormActionContext {
|
||||
schemaRef: Ref<FormSchema[]>;
|
||||
handleFormValues: Fn;
|
||||
}
|
||||
/**
|
||||
* @description: Is it upload
|
||||
/**
|
||||
* @description: Is it upload
|
||||
*/
|
||||
export function itemIsUploadComponent(key: keyof ComponentProps) {
|
||||
return uploadItemType.includes(key);
|
||||
}
|
||||
export function itemIsUploadComponent(key: keyof ComponentProps) {
|
||||
return uploadItemType.includes(key);
|
||||
}
|
||||
function tryConstructArray(field: string, values: Recordable = {}): any[] | undefined {
|
||||
const pattern = /^\[(.+)\]$/;
|
||||
if (pattern.test(field)) {
|
||||
@@ -146,7 +146,7 @@ export function useFormEvents({
|
||||
}
|
||||
}
|
||||
validKeys.push(key);
|
||||
return
|
||||
return;
|
||||
}
|
||||
// Adapt common component
|
||||
if (hasKey) {
|
||||
|
@@ -59,6 +59,7 @@
|
||||
import UploadPreviewModal from './components/UploadPreviewModal.vue';
|
||||
import { BaseFileItem } from './types/typing';
|
||||
import { buildUUID } from '@/utils/uuid';
|
||||
|
||||
defineOptions({ name: 'BasicUpload' });
|
||||
|
||||
const props = defineProps(uploadContainerProps);
|
||||
@@ -86,9 +87,9 @@
|
||||
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) => {
|
||||
return item[valueKey];
|
||||
});
|
||||
@@ -113,7 +114,7 @@
|
||||
} else if (typeof v == 'string') {
|
||||
values.push(v);
|
||||
}
|
||||
fileList.value = values.map((item,i) => {
|
||||
fileList.value = values.map((item, i) => {
|
||||
if (item && isString(item)) {
|
||||
return {
|
||||
uid: buildUUID(),
|
||||
@@ -127,19 +128,19 @@
|
||||
}) as any;
|
||||
}
|
||||
emit('update:value', values);
|
||||
if(!isFirstRender.value){
|
||||
if (!isFirstRender.value) {
|
||||
emit('change', values);
|
||||
isFirstRender.value = false
|
||||
isFirstRender.value = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
||||
// 上传modal保存操作
|
||||
function handleChange(urls: string[],valueKey:string) {
|
||||
function handleChange(urls: string[], valueKey: string) {
|
||||
fileList.value = [...unref(fileList), ...(genFileListByUrls(urls) || [])];
|
||||
const values = getValue(valueKey);
|
||||
emit('update:value', values);
|
||||
@@ -147,7 +148,7 @@
|
||||
}
|
||||
|
||||
// 预览modal保存操作
|
||||
function handlePreviewChange(fileItems: string[],valueKey:string) {
|
||||
function handlePreviewChange(fileItems: string[], valueKey: string) {
|
||||
fileList.value = [...(fileItems || [])];
|
||||
const values = getValue(valueKey);
|
||||
emit('update:value', values);
|
||||
|
@@ -63,7 +63,7 @@
|
||||
const fileList = ref<UploadProps['fileList']>([]);
|
||||
const isLtMsg = ref<boolean>(true);
|
||||
const isActMsg = ref<boolean>(true);
|
||||
const isFirstRender = ref<boolean>(true)
|
||||
const isFirstRender = ref<boolean>(true);
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
@@ -95,13 +95,13 @@
|
||||
}) as UploadProps['fileList'];
|
||||
}
|
||||
emit('update:value', value);
|
||||
if(!isFirstRender.value){
|
||||
if (!isFirstRender.value) {
|
||||
emit('change', value);
|
||||
isFirstRender.value = false
|
||||
isFirstRender.value = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
@@ -23,6 +23,7 @@
|
||||
import { BasicColumn } from '@/components/Table';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { buildUUID } from '@/utils/uuid';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
|
||||
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 = {
|
||||
handleRemove: (record: Record<handleFnKey, any>) => any;
|
||||
handleAdd: (record: Record<handleFnKey, any>) => any;
|
||||
|
@@ -1,13 +1,7 @@
|
||||
import { withInstall } from '@/utils';
|
||||
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';
|
||||
|
||||
export const VxeBasicTable = withInstall(vxeBasicTable);
|
||||
export * from 'vxe-table';
|
||||
export * from './src/types';
|
||||
|
||||
VxeUI.use(VXETablePluginAntd).use(VXETablePluginExportXLSX, { ExcelJS });
|
||||
|
@@ -28,11 +28,6 @@
|
||||
"cancelText": "Close",
|
||||
"okText": "Confirm"
|
||||
},
|
||||
"excel": {
|
||||
"exportModalTitle": "Export data",
|
||||
"fileType": "File type",
|
||||
"fileName": "File name"
|
||||
},
|
||||
"form": {
|
||||
"putAway": "Put away",
|
||||
"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": "关闭",
|
||||
"okText": "确认"
|
||||
},
|
||||
"excel": {
|
||||
"exportModalTitle": "导出数据",
|
||||
"fileType": "文件类型",
|
||||
"fileName": "文件名"
|
||||
},
|
||||
"form": {
|
||||
"putAway": "收起",
|
||||
"unfold": "展开",
|
||||
|
@@ -35,17 +35,9 @@
|
||||
"cropperImage": "图片裁剪",
|
||||
"cardList": "卡片列表"
|
||||
},
|
||||
"excel": {
|
||||
"excel": "Excel",
|
||||
"customExport": "选择导出格式",
|
||||
"jsonExport": "JSON数据导出",
|
||||
"arrayExport": "Array数据导出",
|
||||
"importExcel": "导入"
|
||||
},
|
||||
"feat": {
|
||||
"feat": "功能",
|
||||
"icon": "图标",
|
||||
"screenShot": "截图",
|
||||
"sessionTimeout": "登录过期",
|
||||
"tabs": "标签页操作",
|
||||
"tabDetail": "标签详情页",
|
||||
|
@@ -23,14 +23,6 @@ const feat: AppRouteModule = {
|
||||
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',
|
||||
name: 'WebSocket',
|
||||
@@ -56,14 +48,6 @@ const feat: AppRouteModule = {
|
||||
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',
|
||||
name: 'TabsDemo',
|
||||
@@ -228,51 +212,6 @@ const feat: AppRouteModule = {
|
||||
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',
|
||||
name: 'TestTab',
|
||||
|
@@ -169,7 +169,7 @@ const setting: ProjectConfig = {
|
||||
showBreadCrumbIcon: false,
|
||||
|
||||
// Use error-handler-plugin
|
||||
useErrorHandle: false,
|
||||
useErrorHandle: true,
|
||||
|
||||
// Whether to open back to top
|
||||
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