前端pdf.js将pdf转为图片,尤其适合电子发票打印
写这个的原因就是打电子发票不方便,这个代码是纯js不需要后端服务直接将两张电子发票的pdf转为两张图片渲染到一张A4纸上面(完全不浪费,发票也不会变大),自动完成打印分页,点击打印即可。亲测可用所有电子发票。
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>PDF文件转图片</title><script type="text/javascript" src="js/jquery-3.6.4.min.js"></script><script type="text/javascript" src="js/2.2.228pdf.min.js"></script><script type="text/javascript" src="js/2.2.228.pdf.worker.min.js"></script><!--<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.2.228/pdf.min.js" integrity="sha512-Q0SyiCpjyVOjMJ28RDpmCxi0Drmc9cr7fBQuW2F5F7yiS0yTWtbbltd+H5BYhaA7Izpm6nyIXAUppQfdm6zt1w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.2.228/pdf.worker.min.js" integrity="sha512-kxBikBDcUHWvfvzNZVSRe+1mJ2MSHFe5+WVUCdTTUN3oHo/3GWPDUhiO0jtFCUcs+VnSk6BMGYC3IGuwe3qXVg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>--><script type="text/javascript" src="js/jszip.js"></script><script type="text/javascript" src="js/FileSaver.js"></script><style type="text/css">button {width: 120px;height: 30px;background: none;border: 1px solid #b1afaf;border-radius: 5px;font-size: 12px;font-weight: 1000;color: #384240;cursor: pointer;outline: none;margin: 0 0.5%}button:hover {background: #ccc;}#container {width: 65%;height: 75%;margin-top: 1%;border-radius: 2px;/*border: 2px solid #a29b9b;*/}.pdfInfos {margin: 0 2%;}</style></head><body><div class="showdata" style="margin-top:1%"><button id="pdf_tourl">合并多个pdf为一个</button><button id="prevpage">上一页</button><button id="nextpage">下一页</button><button id="exportImg">导出每一张图片</button><button onclick="wind_print()">打印</button><button onclick="choosePdf()">选择多个pdf文件</button><input style="display:none" id='chooseFile' type='file' accept="application/pdf" multiple="multiple"></div><div class="showdata" style="margin-top:1%"><span class="pdfInfos">页码:<span id="currentPages"></span><span id="totalPages"></span></span><span class="pdfInfos">文件名:<span id="fileName"></span></span><span class="pdfInfos">文件大小:<span id="fileSize"></span></span></div><div style="position: relative;"><div id="container"></div><img id="imgloading" style="position: absolute;top: 20%;left: 2%;display:none" src="loading.gif"></div></body><script>$("#pdf_tourl").click(function(){alert("可以使用PDF Arranger软件");});function wind_print(){$(".showdata").hide();$("#container").css("width","100%");$("#container").css("height","100%");window.print();$(".showdata").show();$("#container").css("width","65%");$("#container").css("height","75%");}var currentPages, totalPages //声明一个当前页码及总页数变量var scale = 2; //设置缩放比例,越大生成图片越清晰$('#chooseFile').change(function() {var pdfFilePath = $('#chooseFile').val();if (pdfFilePath) {//$("#imgloading").css('display', 'block');$("#container").empty(); //清空上一PDF文件展示图currentPages = 1; //重置当前页数totalPages = 0; //重置总页数debuggervar filesdata = $('#chooseFile')[0].files; //jquery获取到文件 返回属性的值//文件大小var fileSize=0;for (let i = 0; i < filesdata.length; i++) {fileSize += filesdata[i].size;}var mb;if (fileSize) {mb = fileSize / 1048576;if (mb > 10) {alert("文件大小不能>10M");return;}}if (filesdata.length === 1) {$("#fileName").text(filesdata[0].name);} else {$("#fileName").text(filesdata[0].name + "等 " + filesdata.length + " 个文件");}$("#fileSize").text(mb.toFixed(2) + "Mb");//reader.readAsDataURL(filesdata[0]); //将文件读取为 DataURLfor (let j = 0; j < filesdata.length; j++) {var reader = new FileReader();reader.readAsDataURL(filesdata[j]);reader.onload = function(e) { //文件读取成功完成时触发pdfjsLib.getDocument(this.result).then(function(pdf) { //调用pdf.js获取文件if (pdf) {totalPages = pdf.numPages; //获取pdf文件总页数$("#currentPages").text("1/");$("#totalPages").text(totalPages);//遍历动态创建canvasfor (var i = 1; i <= totalPages; i++) {var canvas = document.createElement('canvas');var cid=j+i;canvas.id = "pageNum" + cid;$("#container").append(canvas);var context = canvas.getContext('2d');renderImg(pdf, i, context);}}});};}}});//渲染生成图片function renderImg(pdfFile, pageNumber, canvasContext) {pdfFile.getPage(pageNumber).then(function(page) { //逐页解析PDFvar viewport = page.getViewport(scale); // 页面缩放比例var newcanvas = canvasContext.canvas;//设置canvas真实宽高newcanvas.width = viewport.width;newcanvas.height = viewport.height;//设置canvas在浏览中宽高newcanvas.style.width = "100%";newcanvas.style.height = "100%";//默认显示第一页,其他页隐藏if (pageNumber != 1) {newcanvas.style.display = "none";}var renderContext = {canvasContext: canvasContext,viewport: viewport};page.render(renderContext); //渲染生成});//$("#imgloading").css('display', 'none');return;};//上一页$("#prevpage").click(function() {if (!currentPages || currentPages <= 1) {return;}nowpage = currentPages;currentPages--;$("#currentPages").text(currentPages + "/");var prevcanvas = document.getElementById("pageNum" + currentPages);var currentcanvas = document.getElementById("pageNum" + nowpage);currentcanvas.style.display = "none";prevcanvas.style.display = "block";})//下一页$("#nextpage").click(function() {if (!currentPages || currentPages >= totalPages) {return;}nowpage = currentPages;currentPages++;$("#currentPages").text(currentPages + "/");var nextcanvas = document.getElementById("pageNum" + currentPages);var currentcanvas = document.getElementById("pageNum" + nowpage);currentcanvas.style.display = "none";nextcanvas.style.display = "block";})//导出图片$("#exportImg").click(function() {if (!$('#chooseFile').val()) {alert('请先上传pdf文件')return false;}//$("#imgloading").css('display', 'block');var zip = new JSZip(); //创建一个JSZip实例var images = zip.folder("images"); //创建一个文件夹用来存放图片//遍历canvas,将其生成图片放进文件夹images中$("canvas").each(function(index, ele) {var canvas = document.getElementById("pageNum" + (index + 1));//将图片放进文件夹images中//参数1为图片名称,参数2为图片数据(格式为base64,需去除base64前缀 data:image/png;base64)images.file("photo-" + (index + 1) + ".png", splitBase64(canvas.toDataURL("image/png", 1.0)), {base64: true});})//打包下载zip.generateAsync({type: "blob"}).then(function(content) {//saveAs(content, "picture.zip"); //saveAs依赖的js文件是FileSaver.jssaveAs(content, "imgFiles.zip"); //saveAs依赖的js文件是FileSaver.js//$("#imgloading").css('display', 'none');});});//截取base64前缀function splitBase64(dataurl) {var arr = dataurl.split(',')return arr[1]}function choosePdf() {$("#chooseFile").click()}</script>
</html>
相关文章:
前端pdf.js将pdf转为图片,尤其适合电子发票打印
写这个的原因就是打电子发票不方便,这个代码是纯js不需要后端服务直接将两张电子发票的pdf转为两张图片渲染到一张A4纸上面(完全不浪费,发票也不会变大),自动完成打印分页,点击打印即可。亲测可用所有电子发…...

第四百四十三回
文章目录 1. 概念介绍2. 思路与方法2.1 整体思路2.2 使用方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"自定义Action菜单"相关的内容,本章回中将介绍如何获取屏幕相关参数.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在本…...

一分钟快速用上号称“音乐版ChatGPT”的suno AI,适合普通人的超简单教程!
随着AI的应用变广,各类AI程序已逐渐普及。AI已逐渐深入到人们的工作生活方方面面。而AI涉及的行业也越来越多,从最初的写作,到医疗教育,再到现在的音乐。 Suno是一个专业高质量的AI歌曲和音乐创作平台,用户只需输入简…...

干货!一文读懂:位像素海外仓系统的分销功能
随着跨境电商的蓬勃发展,海外仓系统的重要性日益凸显,成为企业在激烈市场竞争中脱颖而出的关键。当谈及海外仓系统的拓展功能,特别是其中的分销功能,正逐渐成为卖家们不可或缺的工具。 那么,这个神奇的分销功能究竟是…...
【洛谷】P1449 后缀表达式
题目描述 所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。 本题中运算符仅包含 -*…...

【MySQL】聚合函数和分组聚合
👦个人主页:Weraphael ✍🏻作者简介:目前学习计网、mysql和算法 ✈️专栏:MySQL学习 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬…...

RDD算子(四)、血缘关系、持久化
1. foreach 分布式遍历每一个元素,调用指定函数 val rdd sc.makeRDD(List(1, 2, 3, 4)) rdd.foreach(println) 结果是随机的,因为foreach是在每一个Executor端并发执行,所以顺序是不确定的。如果采集collect之后再调用foreach打印…...

51之定时器与中断系统
目录 1.定时器与中断系统简介 1.1中断系统 1.2定时器 1.2.1定时器简介 1.2.2定时器大致原理及其配置 1.2.3定时器所需的所有配置总介 2.定时器0实现LED闪烁 3.使用软件生成定时器初始化程序 1.定时器与中断系统简介 1.1中断系统 首先,我们需要来了解一下什么…...

C语言中的内存函数
相比于内存函数,字符串函数和字符函数是对字符串和字符进行操作,内存函数是对内存进行操的。下面跟大家分享我学到的几个内存函数。 memcpy函数 void* memcpy(void* dest, const void* sour, size_t num); dest是目标地址,sour要拷贝的源地…...

JS继承与原型、原型链
在 JavaScript 中,继承是实现代码复用和构建对象关系的重要概念。本文将讨论原型链继承、构造函数继承以及组合继承等几种常见的继承方式,并提供相应的示例代码,并分析它们的特点、优缺点以及适用场景。 在开始讲解 JavaScript 的继承方式之…...

C#基础知识总结
C语言、C和C#的区别 ✔ 面向对象编程(OOP): C 是一种过程化的编程语言,它不直接支持面向对象编程。然而,C 是一种支持 OOP 的 C 的超集,它引入了类、对象、继承、多态等概念。C# 是完全面向对象的ÿ…...
机器学习模型——决策树
决策树的定义: 决策树利用树形数据结构来展示决策规则和分类结果,它是一种归纳学习算法,可以将复杂数据转化为可以预测未知数据的模型。每一条从根节点到叶节点的路径都代表一条决策规则。 决策树内的一些重要名词: 信息熵&am…...

【HTML】制作一个简单的三角形动态图形
目录 前言 开始 HTML部分 CSS部分 效果图 总结 前言 无需多言,本文将详细介绍一段HTML和CSS代码,具体内容如下: 开始 首先新建文件夹,创建两个文本文档,其中HTML的文件名改为[index.html],CSS的文件名…...
Acwing.504 转圈游戏(带取余的快速幂)
题目 n个小伙伴(编号从 0到 n−1)围坐一圈玩游戏。 按照顺时针方向给 n个位置编号,从 0到 n−1。 最初,第 0号小伙伴在第 0号位置,第 1号小伙伴在第 1号位置,…,依此类推。 游戏规…...
pair作为unordered_map的key报错
问题 pair作为unordered_map的key报错,编译时会报错 原因 因为pair没有哈希函数 解决方法 定义哈希函数 template <typename T> inline void hash_combine(std::size_t &seed, const T &val) {seed ^ std::hash<T>()(val) 0x9e3779b9 (…...

Windows提权—数据库提权-mysql提权mssql提权Oracle数据库提权
目录 Windows 提权—数据库提权一、mysql提权1.1 udf提权1.1.2 操作方法一 、MSF自动化--UDF提权--漏洞利用1.1.3 操作方法二、 手工导出sqlmap中的dll1.1.4 操作方法三、 moon.php大马利用 1.2 mof提权1.3 启动项提权1.4 反弹shell 二、MSSQL提权MSSQL提权方法1.使用xp_cmdshe…...
为什么android创建Fragment推荐用newInstance
FullScreenDialogFragment使用newInstance方法不是因为它是一个单例,而是因为这是创建DialogFragment实例并同时提供参数的一种标准模式。这种模式通常称为静态工厂方法模式,在Android开发中被广泛使用,尤其是用于Fragment的实例化。 newIns…...

MyBatis的xml实现方式
1、该项目引入的依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.o…...

大模型prompt技巧——思维链(Chain-of-Thought)
1、Zero-shot、One-shot、Few-shot 与fintune prompt的时候给出例子答案,然后再让模型回答。 2、zero-shot-CoT “Let’s think step by step”有奇迹效果 3、多数投票提高CoT性能——自洽性(Self-consistency) 多个思维链,然后取…...

内网穿透的应用-如何在Android Termux上部署MySQL数据库并实现无公网IP远程访问
文章目录 前言1.安装MariaDB2.安装cpolar内网穿透工具3. 创建安全隧道映射mysql4. 公网远程连接5. 固定远程连接地址 前言 Android作为移动设备,尽管最初并非设计为服务器,但是随着技术的进步我们可以将Android配置为生产力工具,变成一个随身…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...