Vue3+TypeScript实现Docx/Excel预览组件

简介

在现代的 Web 应用中,预览文档和表格是一个常见的需求。本文将介绍如何使用 Vue3 和 TypeScript 开发一个高度可定制的文档和表格预览组件。

技术栈

Vue3

TypeScript

Element Plus

unocss

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,我们可以轻松地开发出高度可定制的文档和表格预览组件。这些组件不仅提供了丰富的功能,还支持多种自定义选项,以满足不同项目的需求。

以上就是Vue3+TypeScript实现Docx/Excel预览组件的详细内容,更多关于Vue3 TypeScript预览组件的资料请关注其它相关文章!

您可能感兴趣的文章: