58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
import * as XLSX from "xlsx";
|
|
import type { WordImportInput, WordRecord } from "@/lib/db";
|
|
|
|
export const wordExcelHeaders = ["词库英语", "中文", "图标/图片"] as const;
|
|
|
|
type WordExcelHeader = (typeof wordExcelHeaders)[number];
|
|
|
|
type WordExcelRow = Record<WordExcelHeader, string>;
|
|
|
|
export function parseWordExcel(buffer: Buffer): WordImportInput[] {
|
|
const workbook = XLSX.read(buffer, { type: "buffer" });
|
|
const sheetName = workbook.SheetNames[0];
|
|
if (!sheetName) {
|
|
throw new Error("表格中没有可导入的工作表");
|
|
}
|
|
|
|
const sheet = workbook.Sheets[sheetName];
|
|
const rows = XLSX.utils.sheet_to_json<Record<string, unknown>>(sheet, {
|
|
defval: "",
|
|
raw: false,
|
|
});
|
|
|
|
return rows.map((row) => ({
|
|
english: readCell(row, "词库英语"),
|
|
chinese: readCell(row, "中文"),
|
|
image: readCell(row, "图标/图片"),
|
|
}));
|
|
}
|
|
|
|
export function buildWordExcel(words: WordRecord[]) {
|
|
const rows: WordExcelRow[] =
|
|
words.length > 0
|
|
? words.map((word) => ({
|
|
词库英语: word.english,
|
|
中文: word.chinese,
|
|
"图标/图片": word.image,
|
|
}))
|
|
: [
|
|
{
|
|
词库英语: "apple",
|
|
中文: "苹果",
|
|
"图标/图片": "🍎",
|
|
},
|
|
];
|
|
|
|
const worksheet = XLSX.utils.json_to_sheet(rows, { header: [...wordExcelHeaders] });
|
|
worksheet["!cols"] = [{ wch: 24 }, { wch: 18 }, { wch: 28 }];
|
|
|
|
const workbook = XLSX.utils.book_new();
|
|
XLSX.utils.book_append_sheet(workbook, worksheet, "词库导入");
|
|
return XLSX.write(workbook, { bookType: "xlsx", type: "buffer" }) as Buffer;
|
|
}
|
|
|
|
function readCell(row: Record<string, unknown>, header: string) {
|
|
const value = row[header];
|
|
return value == null ? "" : String(value).trim();
|
|
}
|