Browse Source

2026-01-26

优化
master
fengyuan_yang 1 month ago
parent
commit
dbc1023930
  1. 103
      src/utils/filePreview.js

103
src/utils/filePreview.js

@ -413,6 +413,105 @@ export async function previewText(blobData, fileName) {
} }
} }
/**
* 清洗工作表数据处理可能导致 sheet_to_html 失败的特殊值
* @param {Object} worksheet - 工作表对象
* @returns {Object} 清洗后的工作表
*/
function sanitizeWorksheet(worksheet) {
if (!worksheet) return worksheet
// 遍历工作表中的所有单元格
Object.keys(worksheet).forEach(cellRef => {
// 跳过特殊属性(如 !ref, !cols, !rows, !merges 等)
if (cellRef.startsWith('!')) return
const cell = worksheet[cellRef]
if (!cell) {
// 如果单元格为 undefined 或 null,设置为空字符串
worksheet[cellRef] = { t: 's', v: '' }
return
}
// 处理单元格值
if (cell.v === undefined || cell.v === null) {
cell.v = ''
cell.t = 's' // 设置类型为字符串
}
// 处理超链接 - 如果超链接目标是 undefined,移除超链接
if (cell.l && (cell.l.Target === undefined || cell.l.Target === null)) {
delete cell.l
}
// 处理富文本 - 如果富文本数组包含 undefined 元素
if (cell.r && Array.isArray(cell.r)) {
cell.r = cell.r.filter(item => item !== undefined && item !== null)
if (cell.r.length === 0) {
delete cell.r
}
}
// 处理公式错误
if (cell.t === 'e' && cell.v === undefined) {
cell.v = '#ERROR!'
}
})
return worksheet
}
/**
* 安全地将工作表转换为HTML
* @param {Object} worksheet - 工作表对象
* @param {Object} options - 转换选项
* @returns {String} HTML字符串
*/
function safeSheetToHtml(worksheet, options = {}) {
try {
// 先清洗数据
const sanitizedSheet = sanitizeWorksheet(worksheet)
return XLSX.utils.sheet_to_html(sanitizedSheet, options)
} catch (error) {
console.warn('sheet_to_html 转换失败,尝试使用 sheet_to_json 方式:', error)
// 备用方案:使用 sheet_to_json 转换后再生成HTML
try {
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: '' })
if (!jsonData || jsonData.length === 0) {
return '<table><tr><td>(空工作表)</td></tr></table>'
}
// 手动生成HTML表格
let html = '<table>'
jsonData.forEach((row, rowIndex) => {
html += '<tr>'
if (Array.isArray(row)) {
row.forEach(cell => {
const tag = rowIndex === 0 ? 'th' : 'td'
// 确保cell值是字符串,处理各种类型
let cellValue = ''
if (cell !== undefined && cell !== null) {
cellValue = String(cell)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
}
html += `<${tag}>${cellValue}</${tag}>`
})
}
html += '</tr>'
})
html += '</table>'
return html
} catch (jsonError) {
console.error('备用转换方案也失败:', jsonError)
return '<table><tr><td>(工作表解析失败)</td></tr></table>'
}
}
}
/** /**
* 预览Excel文件 * 预览Excel文件
* @param {ArrayBuffer} arrayBuffer - 文件数据ArrayBuffer格式 * @param {ArrayBuffer} arrayBuffer - 文件数据ArrayBuffer格式
@ -423,11 +522,11 @@ export function previewExcel(arrayBuffer, fileName) {
const workbook = XLSX.read(arrayBuffer, { type: 'array' }) const workbook = XLSX.read(arrayBuffer, { type: 'array' })
const sheetName = workbook.SheetNames[0] const sheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[sheetName] const worksheet = workbook.Sheets[sheetName]
const htmlString = XLSX.utils.sheet_to_html(worksheet, { editable: false })
const htmlString = safeSheetToHtml(worksheet, { editable: false })
// 预先生成所有sheet的HTML // 预先生成所有sheet的HTML
const sheetsHtml = workbook.SheetNames.map(name => { const sheetsHtml = workbook.SheetNames.map(name => {
return XLSX.utils.sheet_to_html(workbook.Sheets[name], { editable: false })
return safeSheetToHtml(workbook.Sheets[name], { editable: false })
}) })
// 创建预览窗口 // 创建预览窗口

Loading…
Cancel
Save