feat(文件预览): 添加对PDF、Word和Excel文件的预览支持

添加新的文件预览组件,支持PDF、Word(docx)、Excel(xlsx/xls)文件类型预览
重构图片预览为独立组件,并添加相关依赖包
This commit is contained in:
砂糖
2026-04-10 08:42:59 +08:00
parent 255a6dc616
commit a19c4e4eaf
7 changed files with 482 additions and 94 deletions

View File

@@ -9,30 +9,19 @@
@close="handleClose"
>
<!-- 图片预览 -->
<div v-if="fileType === 'image'" class="preview-image">
<div class="image-controls">
<el-button type="primary" size="small" @click="zoomIn">放大</el-button>
<el-button type="primary" size="small" @click="zoomOut">缩小</el-button>
<el-button type="primary" size="small" @click="resetZoom">重置</el-button>
</div>
<div class="image-container" ref="imageContainer">
<img
:src="fileUrl"
:style="{ transform: `scale(${scale})` }"
class="preview-image-content"
@wheel="handleWheel"
/>
</div>
</div>
<ImagePreview v-if="fileType === 'image'" :src="fileUrl" />
<!-- PDF预览 -->
<div v-else-if="fileType === 'pdf'" class="preview-pdf">
<iframe
:src="fileUrl"
class="preview-pdf-content"
frameborder="0"
/>
</div>
<PdfPreview v-else-if="fileType === 'pdf'" :src="fileUrl" />
<!-- Word预览 -->
<DocxPreview v-else-if="fileType === 'docx'" :src="fileUrl" />
<!-- Excel预览 (xlsx) -->
<XlsxPreview v-else-if="fileType === 'xlsx'" :src="fileUrl" />
<!-- Excel预览 (xls) -->
<XlsPreview v-else-if="fileType === 'xls'" :src="fileUrl" />
<!-- 不支持的文件类型 -->
<div v-else class="preview-not-supported">
@@ -42,8 +31,21 @@
</template>
<script>
import ImagePreview from './preview/image/index.vue';
import PdfPreview from './preview/pdf/index.vue';
import DocxPreview from './preview/docx/index.vue';
import XlsxPreview from './preview/xlsx/index.vue';
import XlsPreview from './preview/xls/index.vue';
export default {
name: "FilePreview",
components: {
ImagePreview,
PdfPreview,
DocxPreview,
XlsxPreview,
XlsPreview
},
props: {
visible: {
type: Boolean,
@@ -64,8 +66,7 @@ export default {
},
data() {
return {
dialogVisible: false,
scale: 1
dialogVisible: false
};
},
watch: {
@@ -92,6 +93,12 @@ export default {
return 'image';
} else if (ext === 'pdf') {
return 'pdf';
} else if (ext === 'docx') {
return 'docx';
} else if (ext === 'xlsx') {
return 'xlsx';
} else if (ext === 'xls') {
return 'xls';
} else {
return 'other';
}
@@ -100,82 +107,12 @@ export default {
methods: {
handleClose() {
this.$emit('update:visible', false);
},
// 放大图片
zoomIn() {
if (this.scale < 3) {
this.scale += 0.1;
}
},
// 缩小图片
zoomOut() {
if (this.scale > 0.1) {
this.scale -= 0.1;
}
},
// 重置缩放
resetZoom() {
this.scale = 1;
},
// 鼠标滚轮缩放
handleWheel(event) {
event.preventDefault();
const delta = event.deltaY > 0 ? -0.1 : 0.1;
if ((this.scale > 0.1 || delta > 0) && (this.scale < 3 || delta < 0)) {
this.scale += delta;
}
}
}
};
</script>
<style scoped>
.preview-image {
width: 100%;
height: 70vh;
background-color: #f5f7fa;
display: flex;
flex-direction: column;
}
.image-controls {
padding: 10px;
display: flex;
gap: 10px;
border-bottom: 1px solid #e4e7ed;
background-color: #ffffff;
}
.image-container {
flex: 1;
overflow: auto;
display: flex;
justify-content: center;
align-items: flex-start;
padding: 20px;
}
.preview-image-content {
transition: transform 0.3s ease;
cursor: zoom-in;
max-width: 100%;
max-height: 100%;
}
.preview-image-content:hover {
cursor: zoom-in;
}
.preview-pdf {
width: 100%;
height: 70vh;
}
.preview-pdf-content {
width: 100%;
height: 100%;
}
.preview-not-supported {
display: flex;
justify-content: center;