使用 Vue3 + TypeScript 实现 Docx 、Excel 预览组件
简介
在现代的 Web 应用中,预览文档和表格是一个常见的需求。本文将介绍如何使用 Vue3 和 TypeScript 开发一个高度可定制的文档和表格预览组件。
技术栈
- Vue3
- TypeScript
- Element Plus
- unocss
- vue-office
PDF文档预览
Docx 预览组件
功能特点
- 支持的文件格式: 仅支持预览
Docx
类型的文件。 - 自定义选项: 提供丰富的渲染选项,如页面宽度、高度、字体等。
- 通知提示: 在不支持的文件类型时,会弹出通知提示。
组件实现
// types
export interface RenderOptions {
className?: string; // 默认和文档样式类的类名/前缀
inWrapper?: boolean; // 启用在文档内容周围的包装器渲染
ignoreWidth?: boolean; // 禁用页面宽度渲染
ignoreHeight?: boolean; // 禁用页面高度渲染
ignoreFonts?: boolean; // 禁用字体渲染
breakPages?: boolean; // 启用分页在页面断点上
ignoreLastRenderedPageBreak?: boolean; // 禁用在lastRenderedPageBreak元素上的分页
experimental?: boolean; // 启用实验性功能(制表符计算)
trimXmlDeclaration?: boolean; // 如果为true,将从解析之前的xml文档中移除xml声明
useBase64URL?: boolean; // 如果为true,图像、字体等将转换为base 64 URL,否则使用URL.createObjectURL
useMathMLPolyfill?: boolean; // 包括MathML填充,适用于chrome、edge等
showChanges?: boolean; // 启用文档更改的实验性渲染(插入/删除)
debug?: boolean; // 启用额外的日志记录
}
<script setup lang="ts">
import { ref, computed } from "vue";
import VueOfficeDocx from "@vue-office/docx";
import "@vue-office/docx/lib/index.css";
import { ElNotification } from "element-plus";
import { RenderOptions } from "./types";
interface DocxProps {
height?: string; // 组件高度 ==> 非必传(默认为 150px)
customOptions?: RenderOptions; // 配置参数 ==> 非必传(默认为 {})
}
// 接收父组件参数并设置默认值
const props = withDefaults(defineProps<DocxProps>(), {
height: "80vh"
});
const show = ref(false);
const loading = ref(true);
const docx = ref();
const url = ref("http://static.shanhuxueyuan.com/test.docx");
const customStyle = computed(() => {
return {
height: props.height
};
});
const renderedCallback = () => {
loading.value = false;
};
const open = async (src?: string) => {
show.value = true;
if (src) {
url.value = src;
}
fetch(url.value)
.then(response => response.blob())
.then(res => {
if (res.type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document") {
docx.value = res;
} else {
ElNotification({
title: "提示",
message: "目前仅支持预览 Docx 类型的文件",
type: "warning"
});
}
});
};
defineExpose({
open
});
</script>
<template>
<div>
<el-dialog v-model="show" align-center title="预览" width="80%">
<VueOfficeDocx v-loading="loading" :options="customOptions" :style="customStyle" :src="docx" @rendered="renderedCallback" />
</el-dialog>
</div>
</template>
<style lang="scss" scoped></style>
Excel预览组件
功能特点
- 支持的文件格式: 仅支持预览
Excel
类型的文件。 - 自定义选项: 提供丰富的渲染选项,如最小渲染列数、行数等。
- 通知提示: 在不支持的文件类型时,会弹出通知提示。
// types
export interface ExcelRenderOptions {
minColLength: number; // excel最少渲染多少列
minRowLength: number; // excel最少渲染多少行
widthOffset: number; // 在默认渲染的列表宽度上再加10px宽
heightOffset: number; // 在默认渲染的列表高度上再加10px高
beforeTransformData: (workbookData: any) => any; // 修改workbookData的函数类型定义
transformData?: (workbookData: any) => any; // 修改workbookData的函数类型定义
}
<script setup lang="ts">
import { ref, computed } from "vue";
import VueOfficeExcel from "@vue-office/excel";
import "@vue-office/excel/lib/index.css";
import { ElNotification } from "element-plus";
import { type ExcelRenderOptions } from "./types";
interface DocxProps {
height?: string; // 组件高度 ==> 非必传(默认为 150px)
customOptions?: Partial<ExcelRenderOptions>; // 配置参数 ==> 非必传(默认为 {})
}
// 接收父组件参数并设置默认值
const props = withDefaults(defineProps<DocxProps>(), {
height: "80vh"
});
const show = ref(false);
const loading = ref(true);
const docx = ref();
const url = ref("http://static.shanhuxueyuan.com/demo/excel.xlsx");
const customStyle = computed(() => {
return {
height: props.height
};
});
const renderedCallback = () => {
loading.value = false;
};
const open = async (src?: string) => {
show.value = true;
if (src) {
url.value = src;
}
fetch(url.value)
.then(response => response.blob())
.then(res => {
if (res.type == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
docx.value = res;
} else {
ElNotification({
title: "提示",
message: "目前仅支持预览 Excel 类型的文件",
type: "warning"
});
}
});
};
defineExpose({
open
});
</script>
<template>
<div>
<el-dialog v-model="show" align-center title="预览" width="80%">
<VueOfficeExcel
v-loading="loading"
:options="customOptions"
:style="customStyle"
:src="docx"
@rendered="renderedCallback"
/>
</el-dialog>
</div>
</template>
<style lang="scss" scoped></style>
总结
通过使用 Vue3 和 TypeScript,我们可以轻松地开发出高度可定制的文档和表格预览组件。这些组件不仅提供了丰富的功能,还支持多种自定义选项,以满足不同项目的需求。
希望本文能帮助你更好地理解如何开发文档和表格预览组件!如果你有任何问题或建议,请随时提出。
转载自:https://juejin.cn/post/7361623505555079219