Skip to content

Commit

Permalink
excel扩展
Browse files Browse the repository at this point in the history
  • Loading branch information
biancangming committed Mar 15, 2024
1 parent 4aac775 commit eeda404
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 14 deletions.
1 change: 1 addition & 0 deletions example/src/views/xlsxView/demo/xlsxExport/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@[js](./src/views/echartsView/demo/BarEchart/index.vue)
55 changes: 55 additions & 0 deletions example/src/views/xlsxView/demo/xlsxExport/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<template>
<div>
<button @click="exportExcel()">导出excel</button>
<ElTable :data="data">
<ElTableColumn prop="a" label="A"></ElTableColumn>
<ElTableColumn prop="b" label="B"></ElTableColumn>
<ElTableColumn prop="c" label="C"></ElTableColumn>
</ElTable>
</div>
</template>
<script lang="ts" setup>
import { xlsxFileToJson, jsonToXlsxFile } from "howuse/xlsx";
import { loadLocalFile } from "howtools"
import { ElTable, ElTableColumn } from "element-plus"
import "element-plus/es/components/table/style/css"
const table = ref()
watchEffect(() => {
console.log(table.value)
})
const data = [
{
a: 1,
b: 2,
c: 3,
},
{
a: 4,
b: 5,
c: 6,
},
{
a: 7,
b: 8,
c: 9,
}
]
function exportExcel() {
jsonToXlsxFile({
// 表格数据
sheet: [
{
sheetName: "sheet1", // 表格sheet页名称
data: data // 表格数据
}
],
// 替换字段
replaceFields: {
a: "第一列"
}
})
}
</script>
13 changes: 12 additions & 1 deletion example/src/views/xlsxView/demo/xlsxImport/index.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
<template>
<div>
<button @click="importExcel()">加载excel</button>
<div style=" max-height: 200px;overflow: auto;">
{{ refData }}
</div>
</div>
</template>
<script lang="ts" setup>
import { xlsxFileToJson } from "howuse/xlsx";
import { loadLocalFile } from "howtools"
const refData = ref()
function importExcel() {
loadLocalFile().then(files => {
xlsxFileToJson(files[0]).then(console.log)
xlsxFileToJson({
xlsx: files[0],
replaceFields: { "第一列": "a" }
}).then((item) => {
refData.value = item
})
})
}
</script>
10 changes: 9 additions & 1 deletion example/src/views/xlsxView/index.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
<template>
<CodeView title="自适应折线图,其它自适应类似">
<CodeView title="xlsx数据导出">
<XlsxExportDemo />
<template #code>
<XlsxExportCode />
</template>
</CodeView>
<CodeView title="xlsx数据导入">
<XlsxImportDemo />
<template #code>
<XlsxImportCode />
</template>
</CodeView>
</template>
<script setup lang="ts">
import XlsxExportDemo from "./demo/xlsxExport/index.vue";
import XlsxExportCode from "./demo/xlsxExport/index.md";
import XlsxImportDemo from "./demo/xlsxImport/index.vue";
import XlsxImportCode from "./demo/xlsxImport/index.md";
</script>
3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,5 @@
"lodash-es": "^4.17.21",
"mitt": "^3.0.0",
"xlsx": "^0.18.5"
},
"overrides": {
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz"
}
}
4 changes: 3 additions & 1 deletion src/utils/util.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { isDefined } from "@vueuse/core"

/**
* @param {T} val
* @param {} defVal=undefined
* 为某个字段创建一个默认值,即undefined
*/
export function createDef<T = any>(val: T, defVal: T) {
export function createDef<T = any>(val: T, defVal: Exclude<T, undefined>) {
return val === undefined || val === defVal ? defVal : val
}

Expand Down
4 changes: 2 additions & 2 deletions src/xlsx/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// 参考文档 https://docs.sheetjs.com/docs

import { xlsxFileToJson } from "./tools/xlsx-json"
import { xlsxFileToJson, jsonToXlsxFile } from "./tools/xlsx-json"

export { xlsxFileToJson }
export { xlsxFileToJson, jsonToXlsxFile }
60 changes: 54 additions & 6 deletions src/xlsx/tools/xlsx-json.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,71 @@
import { utils } from "xlsx"
import { createDef } from "howuse/utils/util"
import { utils, writeFile } from "xlsx"
import { readXlsx } from "./xlsx"

export function xlsxFileToJson(xlsx: File): Promise<Record<string, any>> {

export interface XlsxImportOpts {
xlsx: File,
replaceFields?: Record<string, string>
}

export function xlsxFileToJson(opts: XlsxImportOpts): Promise<Record<string, any>> {
const replaceFields = createDef(opts.replaceFields, {})

return new Promise((resolve, reject) => {
readXlsx(xlsx).then(wb => {
if (!opts.xlsx) {
reject("xlsx is required")
return
}

readXlsx(opts.xlsx).then(wb => {
if (wb.SheetNames.length <= 0) {
reject("表格内容为空,请检查...")
}

const sheetJson = {}
for (const sheetName of wb.SheetNames) {
const data = utils.sheet_to_json(wb.Sheets[sheetName])
const data = utils.sheet_to_json(wb.Sheets[sheetName]) as any[]
// 替换Excel当中的标题
for (const item of data) {
for (const [key, value] of Object.entries(item)) {
delete item[key]
item[replaceFields[key] || key] = value
}
}

sheetJson[sheetName] = data
}
resolve(sheetJson)
})
}).catch(reject)
})
}

function jsonToXlsx(json: any) {

// fieldOrder 排序之后的key顺序
export interface XlsxExportOpts {
sheet: { sheetName: string, data: any }[]
fileName?: string,
replaceFields?: Record<string, string>
}

export function jsonToXlsxFile(xlsxData: XlsxExportOpts) {
const fileName = createDef(xlsxData.fileName, "demo.xlsx")
const replaceFields = createDef(xlsxData.replaceFields, {})
// 创建工作簿
const wb = utils.book_new();

for (const { sheetName, data } of xlsxData.sheet) {
// 替换表格当中的标题
for (const item of data) {
for (const [key, value] of Object.entries(item)) {
delete item[key]
item[replaceFields[key] || key] = value
}
}
const sheet = utils.json_to_sheet(data);
// 将工作表放入工作簿中
utils.book_append_sheet(wb, sheet, sheetName);
// 生成文件并下载
}
writeFile(wb, fileName);
}

0 comments on commit eeda404

Please sign in to comment.