| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- import papa from 'papaparse'
- import ExcelJS from 'exceljs'
- const ibpsExcel = {
- // 导入 CSV(保持原逻辑不变)
- csv (file) {
- return new Promise((resolve, reject) => {
- papa.parse(file, {
- header: true,
- skipEmptyLines: true,
- complete: (results) => resolve(results),
- error: (err) => reject(err)
- })
- })
- },
- // 导入 Excel(支持图片)
- async xlsx (file, options = { raw: false }) {
- const reader = new FileReader()
- return new Promise((resolve, reject) => {
- reader.onload = async (e) => {
- try {
- const buffer = new Uint8Array(e.target.result)
- const workbook = new ExcelJS.Workbook()
- await workbook.xlsx.load(buffer)
- const worksheet = workbook.worksheets[0]
- const { header, imagesMap } = this.processSheetMeta(workbook, worksheet)
- const results = this.processSheetData(worksheet, header, imagesMap, options)
- resolve({ header, results })
- } catch (error) {
- reject(error)
- }
- }
- reader.readAsArrayBuffer(file)
- })
- },
- // 处理工作表元数据(表头+图片)
- processSheetMeta (workbook, worksheet) {
- // 处理表头
- const header = []
- worksheet.getRow(1).eachCell({ includeEmpty: true }, (cell, colNumber) => {
- header[colNumber - 1] = cell.text?.trim() || `列${colNumber}`
- })
- // 处理图片映射
- const imagesMap = new Map()
- worksheet.getImages().forEach((img, index) => {
- const { tl } = img.range
- const image = workbook.getImage(img.imageId)
- // console.log(img, image)
- // 检查图片数据是否存在
- if (!image || !image.buffer) {
- console.warn(`图片数据不存在或未正确加载,图片ID: ${img.imageId}`)
- return
- }
- // 只处理数据行(行号 >= 2)
- const rowIndex = Math.floor(tl.row) - 1 // 转换为结果数组索引
- if (rowIndex < 0) return
- // 生成唯一键:行索引_列索引_图片索引(避免 imageId 重复)
- const colIndex = Math.floor(tl.col)
- const mapKey = `${rowIndex}_${colIndex}_${index}`
- // 转换图片为 base64
- const base64 = this.arrayBufferToBase64(image.buffer)
- const imageData = {
- name: image.name,
- type: image.type,
- ext: image.extension,
- dimensions: image.size,
- data: `data:${this.getMimeType(image)};base64,${base64}`
- }
- imagesMap.set(mapKey, imageData)
- })
- return { header, imagesMap }
- },
- // 处理工作表数据
- processSheetData (worksheet, header, imagesMap, options) {
- const results = []
- worksheet.eachRow((row, rowNumber) => {
- if (rowNumber === 1) return // 跳过表头
- const rowData = { _images: {}}
- // 遍历所有列,确保每列都有属性值
- header.forEach((colName, colIndex) => {
- const cell = row.getCell(colIndex + 1) // 列索引从 1 开始
- const key = colName
- // 处理单元格值
- rowData[key] = options.raw ? cell.value : cell.text || '' // 为空时赋默认值
- // 处理关联图片
- const mapKeyPrefix = `${rowNumber - 2}_${colIndex}`
- for (const [mapKey, imageData] of imagesMap.entries()) {
- if (mapKey.startsWith(mapKeyPrefix)) {
- rowData._images[key] = imageData
- }
- }
- })
- results.push(rowData)
- })
- return results
- },
- // ArrayBuffer 转 Base64
- arrayBufferToBase64 (buffer) {
- let binary = ''
- new Uint8Array(buffer).forEach(byte => {
- binary += String.fromCharCode(byte)
- })
- return btoa(binary)
- },
- // 获取图片 MIME 类型
- getMimeType (image) {
- const types = {
- png: 'image/png',
- jpeg: 'image/jpeg',
- gif: 'image/gif',
- bmp: 'image/bmp'
- }
- return types[image.extension] || 'application/octet-stream'
- }
- }
- export default ibpsExcel
|