vue3预览pdf可旋转并拖拽盖章任意位置生成新文件
<p>对pdf旋转、拖拽公章或其他图片到pdf任意位置,生成一个新的pdf进行下载</p><p>网上搜了一下代码量都挺大的,这里自己来实现一个吧!</p>
<p>涉及到的技术栈:pdfjs-dist、pdf-lib、vueuse</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">setup</span><span style="color: rgba(0, 0, 255, 1)">></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
import { ref, onMounted, computed } from </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">vue</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
import </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">*</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> as pdfjsLib from </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">pdfjs-dist/build/pdf</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
import { useDraggable } from </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">@vueuse/core</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
import { PDFDocument,degrees} from </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">pdf-lib</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
import img2 from </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">@/assets/222.jpg</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 这里的文件从node_modules/pdfjs-dist/build/目录下复制到public目录下</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">pdfjsLib.GlobalWorkerOptions.workerSrc </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> `.</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">/</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">pdf.worker.mjs`;</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
const pdfCanvases </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref([]);
const pageCount </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
const pdfCanvasContainer </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">null</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
const rotation </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">); </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 添加旋转角度变量</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
const imgRef </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">null</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
const pdfWidth </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
const pdfHeight </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
const pdfTotalHeight </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
const myImage </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">null</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
const imageWidth </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
const imageHeight </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 存储初始位置</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">const initialX </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
const initialY </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 最后停留的位置</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">const finalX </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
const finalY </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ref(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
const getImageSize </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> () </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">if</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (myImage.value) {
imageWidth.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> myImage.value.naturalWidth;
imageHeight.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> myImage.value.naturalHeight;
}
};
const { x, y, style } </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> useDraggable(imgRef);
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 计算考虑滚动偏移后的样式</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">const draggableStyle </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> computed(() </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
let newX </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> x.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">+</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> window.scrollX;
let newY </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> y.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">+</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> window.scrollY;
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 边界检查,直接限制在 PDF 边界内</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">newX </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Math.max(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">, Math.min(newX, pdfWidth.value));
newY </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Math.max(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">, Math.min(newY, pdfTotalHeight.value));
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">if</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (newX </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">+</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> imageWidth.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">>=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pdfWidth.value) {
newX </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pdfWidth.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">-</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> imageWidth.value;
}
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">if</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (newY </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">+</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> imageHeight.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">>=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pdfTotalHeight.value) {
newY </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pdfTotalHeight.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">-</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> imageHeight.value;
}
finalX.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> newX;
finalY.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> newY;
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">return</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
transform: `translate(${newX}px, ${newY}px)`,
};
});
onMounted(() </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
loadPdf(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">download.pdf</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 获取初始位置</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">initialX.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> x.value;
initialY.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> y.value;
});
const loadPdf </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> async (url) </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">try</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 清除旧的 canvas</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">if</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (pdfCanvasContainer.value) {
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">while</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (pdfCanvasContainer.value.firstChild) {
pdfCanvasContainer.value.removeChild(pdfCanvasContainer.value.firstChild);
}
}
const loadingTask </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pdfjsLib.getDocument(url);
const pdf </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> await loadingTask.promise;
pageCount.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pdf.numPages;
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 清空画布数组</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pdfCanvases.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> [];
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">for</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (let pageNumber </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">1</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">; pageNumber </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"><=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pdf.numPages; pageNumber</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">++</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">) {
const page </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> await pdf.getPage(pageNumber);
const scale </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">1</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
let viewport </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> page.getViewport({ scale });
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 应用旋转</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> viewport </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> page.getViewport({ scale, rotation: rotation.value });
const canvas </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> document.createElement(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">canvas</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">); </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 直接创建 canvas 元素</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> canvas.height </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> viewport.height;
canvas.width </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> viewport.width;
pdfCanvases.value.push(canvas); </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 将创建的 canvas 添加到数组中</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
const context </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> canvas.getContext(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">2d</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
const renderContext </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
canvasContext: context,
viewport,
};
await page.render(renderContext).promise;
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 获取第一页的尺寸作为 PDF 预览区域的尺寸</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">if</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (pageNumber </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">===</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">1</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">) {
pdfWidth.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> viewport.width;
pdfHeight.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> viewport.height;
pdfTotalHeight.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> viewport.height </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">*</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pdf.numPages;
}
}
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 将动态创建的 canvas 添加到模板中</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">if</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (pdfCanvasContainer.value) {
pdfCanvases.value.forEach((canvas) </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
pdfCanvasContainer.value.appendChild(canvas);
});
}
} </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">catch</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (error) {
console.error(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">Error loading PDF:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">, error);
}
};
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 恢复初始位置</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">const resetPosition </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> () </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
x.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> initialX.value;
y.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> initialY.value;
};
const generatePdf </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> async () </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">try</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
const pdfBytes </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> await fetch(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">download.pdf</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">).then((res) </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> res.arrayBuffer());
const pdfDoc </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> await PDFDocument.load(pdfBytes);
const imageBytes </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> await fetch(img2).then((res) </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> res.arrayBuffer());
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 检测 MIME 类型</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> const mimeType </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> await detectMimeType(imageBytes);
let image;
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">if</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (mimeType </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">===</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">image/jpeg</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">) {
image </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> await pdfDoc.embedJpg(imageBytes);
} </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">else</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">if</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (mimeType </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">===</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">image/png</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">) {
image </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> await pdfDoc.embedPng(imageBytes);
} </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">else</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
console.error(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">Unsupported image format.</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">return</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
}
const pages </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pdfDoc.getPages();
const firstPage </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pages; </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 将图片添加到第一页,你可以根据需要修改</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
pages.forEach(page</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">{
page.setRotation(degrees(rotation.value));
})
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 计算图片相对于当前页面的 y 坐标</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> const pageY </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> finalY.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">%</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pdfHeight.value;
firstPage.drawImage(image, {
x: rotation.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">===</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">90</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">?</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(firstPage.getHeight() </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">-</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pageY </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">-</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> imageHeight.value):finalX.value,
y: rotation.value </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">===</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">90</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">?</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">finalX.value:firstPage.getHeight() </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">-</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> pageY </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">-</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> imageHeight.value, </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 注意:pdf-lib 的坐标系原点在左下角</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> width: imageWidth.value,
height: imageHeight.value,
});
const modifiedPdfBytes </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> await pdfDoc.save();
const blob </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">new</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Blob(, { type: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">application/pdf</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> });
const link </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> document.createElement(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">a</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
link.href </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> window.URL.createObjectURL(blob);
link.download </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">merged.pdf</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
link.click();
} </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">catch</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (error) {
console.error(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">Error generating PDF:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">, error);
}
};
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 检测 MIME 类型的辅助函数</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">const detectMimeType </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (arrayBuffer) </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">return</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">new</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Promise((resolve, reject) </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
const reader </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">new</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> FileReader();
reader.onload </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> () </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
const uint8Array </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">new</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Uint8Array(reader.result);
let mimeType </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">''</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">if</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (uint8Array[</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">] </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">===</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0xff</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">&&</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> uint8Array[</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">1</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">] </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">===</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0xd8</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">&&</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> uint8Array[</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">2</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">] </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">===</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0xff</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">) {
mimeType </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">image/jpeg</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
} </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">else</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">if</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (
uint8Array[</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">] </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">===</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0x89</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">&&</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
uint8Array[</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">1</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">] </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">===</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0x50</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">&&</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
uint8Array[</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">2</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">] </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">===</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0x4e</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">&&</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
uint8Array[</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">3</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">] </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">===</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0x47</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
) {
mimeType </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">image/png</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
} </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">else</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
mimeType </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">unknown</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
}
resolve(mimeType);
};
reader.onerror </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> reject;
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 将 ArrayBuffer 转换为 Blob</span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> const blob </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">new</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Blob();
reader.readAsArrayBuffer(blob);
});
};
const rota </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ()</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=></span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">{
loadPdf(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">download.pdf</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
}</span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">template</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">style</span><span style="color: rgba(0, 0, 255, 1)">="position: absolute;left: 50px"</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">></span><span style="color: rgba(0, 0, 0, 1)">
{{ style }}
</span><span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">button </span><span style="color: rgba(255, 0, 0, 1)">@click</span><span style="color: rgba(0, 0, 255, 1)">="resetPosition"</span><span style="color: rgba(0, 0, 255, 1)">></span>恢复初始位置<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">button</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">button </span><span style="color: rgba(255, 0, 0, 1)">@click</span><span style="color: rgba(0, 0, 255, 1)">="generatePdf"</span><span style="color: rgba(0, 0, 255, 1)">></span>生成 PDF<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">button</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">label</span><span style="color: rgba(0, 0, 255, 1)">></span>旋转角度:<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">label</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="number"</span><span style="color: rgba(255, 0, 0, 1)"> v-model.number</span><span style="color: rgba(0, 0, 255, 1)">="rotation"</span><span style="color: rgba(255, 0, 0, 1)"> step</span><span style="color: rgba(0, 0, 255, 1)">="90"</span> <span style="color: rgba(0, 0, 255, 1)">/></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">button </span><span style="color: rgba(255, 0, 0, 1)">@click</span><span style="color: rgba(0, 0, 255, 1)">="rota"</span><span style="color: rgba(0, 0, 255, 1)">></span>转换<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">button</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">style</span><span style="color: rgba(0, 0, 255, 1)">="position: absolute"</span><span style="color: rgba(255, 0, 0, 1)"> ref</span><span style="color: rgba(0, 0, 255, 1)">="imgRef"</span><span style="color: rgba(255, 0, 0, 1)"> :style</span><span style="color: rgba(0, 0, 255, 1)">="draggableStyle"</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">img </span><span style="color: rgba(255, 0, 0, 1)">ref</span><span style="color: rgba(0, 0, 255, 1)">="myImage"</span><span style="color: rgba(255, 0, 0, 1)"> src</span><span style="color: rgba(0, 0, 255, 1)">="@/assets/222.jpg"</span><span style="color: rgba(255, 0, 0, 1)"> alt</span><span style="color: rgba(0, 0, 255, 1)">="静态图片"</span><span style="color: rgba(255, 0, 0, 1)"> @load</span><span style="color: rgba(0, 0, 255, 1)">="getImageSize"</span> <span style="color: rgba(0, 0, 255, 1)">/></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">ref</span><span style="color: rgba(0, 0, 255, 1)">="pdfCanvasContainer"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">template</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">style </span><span style="color: rgba(255, 0, 0, 1)">scoped</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">style</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>
</div><br><br>
来源:https://www.cnblogs.com/sy-zl/p/18959943
頁:
[1]