<template>
<div class="excel-container-preview">
<div class="sheet-tabs">
<button
v-for="(sheetName, index) in sheetNames"
:key="index"
:class="{ active: activeSheetIndex === index }"
@click="activeSheetIndex = index"
>
{{ sheetName }}
</button>
</div>
<div class="excel-preview-wrapper">
<div class="excel-preview" v-html="currentSheetHtml"></div>
</div>
</div>
</template>
<script setup>
import * as XLSX from 'xlsx'
const info = inject('info')
const onPreviewError = inject('onPreviewError')
const sheetNames = ref([])
const sheetHtmls = ref([])
const activeSheetIndex = ref(0)
const loading = ref(true)
const reset = () => {
sheetNames.value = []
sheetHtmls.value = []
activeSheetIndex.value = 0
loading.value = true
}
const render = async () => {
try {
const { _blob } = info.value
reset()
const workbook = await readExcelFromBlob(_blob)
processWorkbook(workbook)
} catch (error) {
onPreviewError(error)
} finally {
loading.value = false
}
}
const readExcelFromBlob = (blob) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader()
fileReader.onload = (e) => {
try {
const data = new Uint8Array(e.target.result)
const workbook = XLSX.read(data, { type: 'array' })
resolve(workbook)
} catch (error) {
reject(error)
}
}
fileReader.onerror = () => reject(new Error('文件读取失败'))
fileReader.readAsArrayBuffer(blob)
})
}
const processWorkbook = (workbook) => {
sheetNames.value = workbook.SheetNames
sheetHtmls.value = sheetNames.value.map((sheetName) => {
const worksheet = workbook.Sheets[sheetName]
const filteredWorksheet = filterEmptyRows(worksheet)
const html = XLSX.utils.sheet_to_html(filteredWorksheet, {
editable: false,
id: `excel-table-${sheetName}`
})
return html.replace('<table', '<table class="excel-table"')
})
}
const filterEmptyRows = (worksheet) => {
const jsonData = XLSX.utils
.sheet_to_json(worksheet, { header: 1, raw: false })
.filter((row) =>
row.some((cell) => cell !== null && cell.toString().trim() !== '')
)
if (jsonData.length === 0) return worksheet
return XLSX.utils.aoa_to_sheet(jsonData)
}
const currentSheetHtml = computed(
() => sheetHtmls.value[activeSheetIndex.value] || ''
)
const resizeObserver = ref(null)
onMounted(() => {
render()
resizeObserver.value = new ResizeObserver((entries) => {
adjustTableWidth()
})
window.addEventListener('resize', adjustTableWidth)
})
const cleanup = () => {
if (resizeObserver.value) {
resizeObserver.value.disconnect()
}
window.removeEventListener('resize', adjustTableWidth)
}
const adjustTableWidth = () => {
nextTick(() => {
const table = document.querySelector('.excel-table')
if (table) {
const containerWidth = document.querySelector(
'.excel-preview-wrapper'
).offsetWidth
table.style.width = 'auto'
const naturalTableWidth = table.offsetWidth
if (naturalTableWidth > containerWidth) {
table.style.width = '100%'
} else {
table.style.width = `${naturalTableWidth}px`
}
}
})
}
watch(activeSheetIndex, () => {
nextTick(() => {
adjustTableWidth()
})
})
onUnmounted(cleanup)
</script>
<style lang="scss">
.excel-container-preview {
max-width: 100%;
overflow-y: auto;
height: calc(100vh - 100px);
.sheet-tabs {
display: flex;
gap: 5px;
margin-bottom: 10px;
overflow-x: auto;
padding-bottom: 5px;
button {
background-color: #f0f0f0;
border: 1px solid #ddd;
padding: 4px 20px;
cursor: pointer;
white-space: nowrap;
&.active {
background-color: #4a86e8;
color: white;
border-color: #4a86e8;
}
}
}
.excel-preview-wrapper {
overflow-x: auto;
max-width: 100%;
}
.excel-preview {
min-width: 100%;
}
.excel-table {
border-collapse: collapse;
table-layout: auto;
th,
td {
border: 1px solid #ddd;
text-align: left;
word-wrap: break-word;
min-width: 150px;
}
th {
background-color: #f2f2f2;
font-weight: bold;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
tr:hover {
background-color: #f5f5f5;
}
}
.error-message {
padding: 20px;
text-align: center;
font-size: 16px;
color: #f44336;
}
}
</style>
前端开发 + Vue3.2/xlsx + 多格式文件预览组件(图片 / PDF/Excel)+ 企业级应用内文件在线查看
需积分: 0 83 浏览量
更新于2025-07-10
收藏 7KB ZIP 举报
该组件聚焦前端开发领域,基于 Vue3.2 框架开发,集成 xlsx 插件实现 Excel 解析,支持图片、PDF、Excel 三类文件的在线预览功能。通过自动识别文件类型并适配对应渲染逻辑(图片原生渲染、PDF 分片加载、Excel 表格化解析),解决了企业级应用中用户需下载文件才能查看内容的痛点,适用于管理系统、文档中心、用户上传反馈等场景,提升了文件查看的便捷性与交互体验。
在当今数字化信息时代,企业级应用对文件处理能力的要求日益提高。传统的文件处理方式,如下载文件后本地查看,已经无法满足快节奏的工作需求。因此,实现文件的在线预览成为了开发者的当务之急。前端开发领域在此方面取得了长足的进步,尤其是在结合了Vue这样的现代化JavaScript框架后,开发者能够更加高效地构建用户界面和交互功能。
Vue3.2作为Vue.js的最新版本,其响应式系统、组合式API以及性能优化等方面都得到了增强。这使得基于Vue3.2开发的组件不仅更加高效,而且更易于维护和扩展。结合xlsx插件,可以轻松实现对Excel文件的解析和操作,这对于需要处理大量表格数据的应用来说尤为重要。
多格式文件在线预览组件正是为了满足企业级应用内文件查看需求而设计。它支持图片、PDF和Excel等常见文件格式的预览功能。具体而言,该组件能够自动识别文件类型并适配相应的渲染逻辑。例如,图片文件可以通过原生HTML标签直接渲染显示,PDF文件则采用分片加载技术,使得即使是大文件也可以实现流畅的预览体验。对于Excel文件,组件通过表格化解析技术,能够将复杂的数据结构转化为清晰可读的表格形式,使用户无需下载即可进行查看和分析。
这种在线预览功能的实现,极大地方便了用户,尤其是那些需要频繁查阅文件内容的办公人员。它不仅节省了下载时间,还减少了本地存储资源的占用,提高了工作效率。此外,良好的用户体验设计使得文件查看过程更加直观和便捷,例如支持缩放、翻页等操作,以及在文件预览时提供准确的导航和搜索功能。
该组件适用于多种企业级应用场景,比如内部管理系统的文件浏览、文档中心的内容管理、用户上传的文件审核等等。在这些场景下,用户可以迅速获取文件信息,及时做出决策或反馈。特别地,对于远程办公或团队协作环境,文件在线预览功能能够提供实时共享和同步的能力,促进了团队成员之间的协作效率。
前端开发领域推出的基于Vue3.2和xlsx插件的多格式文件预览组件,不仅提升了文件处理的技术水平,也为用户提供了更加丰富和高效的交互体验。这不仅是一种技术上的进步,更是适应现代企业工作方式变革的重要一步。

web_Hsir
- 粉丝: 202
最新资源
- (源码)基于 XIAO ESPC3 微控制器的无线 Cyberpuck 鼠标.zip
- 基于COMSOL的单相变压器绕组及铁芯振动形变仿真模型研究与应用
- 基于非支配排序的多目标小龙虾优化算法求解柔性作业车间调度问题(FJSP)的MATLAB实现
- 基于博弈树和NMPC的无信号灯T型路口车辆冲突智能运动规划策略研究 NMPC 终极版
- 移动边缘计算中基于差分进化算法的任务卸载与资源调度研究及MATLAB实现
- 离网风电耦合PEM电解水制氢系统的建模与优化:非并网风电制氢技术的应用研究
- 基于五次多项式的快速自由换道轨迹规划(DLC方法)的MATLAB或Python实现:针对性设计评价成本函数与三车道场景仿真demo
- 基于西门子S7-300PLC与S7-1200PLC的污水处理控制系统全套资料:包含触摸屏仿真画面图纸文档,兼容博图V16及以上版本
- 永磁直驱风力发电系统(PMSG)的并网装置仿真与优化控制策略 2025版
- 燃料电池汽车Cruise-MATLABSimulink联合仿真的多点恒功率控制策略研究
- 基于Lyapunov方法的欠驱动无人船USV路径与轨迹跟踪控制策略实现——11-trans顶刊代码复现 - 非线性控制
- 双馈风力发电机变流器Simulink仿真模型及参数突变研究
- 非奇异快速终端滑模控制(NFTSMC)在三自由度水面艇轨迹跟踪中的应用研究及MatlabSimulink实现
- 基于PLC的S7-1200智能交通灯控制系统:博途编程与Wincc组态仿真及报告研究 WinCC 必备版
- 西门子S7-200PLC与组态王联合打造物料传送带四传送带智能控制系统 终极版
- 西门子S7-200PLC与组态王在三层电梯控制系统中的设计与实现