vue3 实现pdf预览及点击图片列表显示隐藏对应的图片

我这边简单,只是显示pdf文件,然后点击图片切换对应的图片。然后下载的时候能下载出来即可

上代码,装依赖

cnpm install pdf-lib pdfjs-dist file-saver 

  

下面是业务代码

<template>
	<div>
		<!-- 控制面板:选择要嵌入到PDF的图片 -->
		<div class="controls">
			<h3>
				选择要嵌入到PDF的图片:<button class="download-button" @click="downloadModifiedPDF">
					下载包含选中图片的PDF
				</button>
			</h3>
			<div class="image-options">
				<!-- 遍历图片列表,显示每个图片的名称和选中状态 -->
				<label v-for="(image, index) in images" :key="image.id">
					<span @click="imageClick(index)" style="cursor: pointer">
						{{ image.name }} {{ image.checked ? '✔' : '' }}
					</span>
				</label>
			</div>
		</div>

		<!-- PDF预览区域 -->
		<div class="container">
			<div class="pdf-container" id="original-pdf-viewer">
				<h2>原始PDF 文件:</h2>
				<!-- 使用iframe嵌入原始PDF,并隐藏工具栏和菜单栏 -->
				<iframe id="original-pdf-iframe" :src="pdfUrl" width="100%" height="550px" style="border: none"></iframe>
			</div>
			<div class="modified-pdf-container" id="modified-pdf-viewer">
				<h2>修改后的PDF 预览:</h2>
				<!-- 使用iframe嵌入修改后的PDF -->
				<iframe
					id="modified-pdf-iframe"
					:src="modifiedPdfUrl"
					width="100%"
					height="550px"
					style="border: none"
				></iframe>
			</div>
		</div>
		<!-- 显示选中的图片 -->
		<div class="images-container">
			<img
				v-for="image in images"
				:key="image.id"
				:src="image.src"
				:id="image.id"
				v-show="image.checked"
				style="max-width: 150px; margin: 10px; display: inline-block"
			/>
		</div>
	</div>
</template>

<script setup>
	import { ref } from 'vue'
	import { PDFDocument } from 'pdf-lib'
	import { saveAs } from 'file-saver'
	// #toolbar=0:隐藏工具栏。
	// #menubar=0:隐藏菜单栏。
	// #scrollbar=0:隐藏滚动条。
	// #navpanes=0:隐藏导航窗格(缩略图等)。
	// PDF URL和修改后的PDF URL
	const pdfUrl = ref('你pdf文件#toolbar=0')
	const modifiedPdfUrl = ref('')

	// 图片列表
	const images = ref([
		{
			id: 'img1',
			name: '左侧部分图片',
			src: '要展示的文件地址',
			checked: false
		},
		{
			id: 'img2',
			name: '右侧部分图片',
		src: '要展示的文件地址',
			checked: false
		},
		{
			id: 'img3',
			name: '检测专用章',
		src: '要展示的文件地址',
			checked: false
		}
		// ...其他图片
	])

	// 预览修改后的PDF
	const previewModifiedPDF = async () => {
		// 获取选中的图片
		const selectedImages = images.value.filter((image) => image.checked)

		if (selectedImages.length === 0) {
			alert('请选择至少一张图片来嵌入到PDF中。')
			return
		}

		try {
			// 加载原始PDF
			const response = await fetch(pdfUrl.value)
			const existingPdfBytes = await response.arrayBuffer()
			const pdfDoc = await PDFDocument.load(existingPdfBytes)

			// 获取第一页
			const firstPage = pdfDoc.getPages()[0]

			// 图片位置配置
			const imagePositions = {
				img1: { x: 37, y: firstPage.getHeight() - 150, width: 70, height: 50 },
				img2: {
					x: firstPage.getWidth() - 100,
					y: firstPage.getHeight() - 150,
					width: 70,
					height: 50
				},
				img3: { x: 80, y: firstPage.getHeight() / 2 - 210, width: 70, height: 70 }
				// img3: { x: firstPage.getWidth() / 2 - 50, y: firstPage.getHeight() - 150, width: 100, height: 100 }
			}

			// 遍历选中的图片并嵌入到PDF
			for (const imgSrc of selectedImages) {
				const imgResponse = await fetch(imgSrc.src)
				const imgBytes = await imgResponse.arrayBuffer()

				let img
				// 根据图片格式嵌入图片
				if (imgSrc.src.toLowerCase().endsWith('.jpg') || imgSrc.src.toLowerCase().endsWith('.jpeg')) {
					img = await pdfDoc.embedJpg(imgBytes)
				} else if (imgSrc.src.toLowerCase().endsWith('.png')) {
					img = await pdfDoc.embedPng(imgBytes)
				} else {
					alert(`不支持的图片格式:${imgSrc.src}`)
					continue
				}

				// 在PDF上绘制图片
				const pos = imagePositions[imgSrc.id]
				firstPage.drawImage(img, {
					x: pos.x,
					y: pos.y,
					width: pos.width,
					height: pos.height
				})
			}

			// 保存修改后的PDF并生成预览URL
			const modifiedPdfBytes = await pdfDoc.save()
			modifiedPdfUrl.value =
				URL.createObjectURL(new Blob([modifiedPdfBytes], { type: 'application/pdf' })) + '#toolbar=0'
		} catch (error) {
			console.log('预览修改后的PDF时出错:', error)
			alert('在预览PDF时发生错误。请检查控制台获取更多信息。')
		}
	}

	// 下载修改后的PDF
	const downloadModifiedPDF = () => {
		if (!modifiedPdfUrl.value) {
			alert('请先点击“预览”按钮生成修改后的PDF。')
			return
		}

		try {
			saveAs(modifiedPdfUrl.value, 'modified_10086.pdf')
		} catch (error) {
			console.log('下载修改后的PDF时出错:', error)
			alert('在下载PDF时发生错误。请检查控制台获取更多信息。')
		}
	}

	// 切换图片选中状态
	const imageClick = (index) => {
		images.value[index].checked = !images.value[index].checked
		// 如果有选中的图片,则预览修改后的PDF
		if (images.value.filter((item) => item.checked).length > 0) previewModifiedPDF()
	}
</script>
<style>
	body {
		font-family: Arial, sans-serif;
		margin: 20px;
	}
	.controls {
		margin-bottom: 20px;
	}
	.controls label {
		display: block;
		margin: 5px 0;
	}
	.container {
		display: flex;
		gap: 40px;
	}
	.pdf-container,
	.modified-pdf-container {
		border: 1px solid #ccc;
		width: 45%;
		height: 630px;
		overflow: auto;
	}
	.download-button,
	.preview-button {
		padding: 5px;
		font-size: 12px;
	}
	.image-options {
		width: 60%;
		display: flex;

		justify-content: space-between;
	}
	.images-container {
		display: none; /* 初始隐藏 */
		margin-top: 20px;
	}
	.images-container img {
		max-width: 150px;
		margin: 10px;
		display: none; /* 初始隐藏 */
	}
</style>

  

 

posted @ 2025-01-02 15:44  好运的菜狗  阅读(484)  评论(0)    收藏  举报