当前位置: 首页 > news >正文

前端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转为图片,尤其适合电子发票打印

写这个的原因就是打电子发票不方便&#xff0c;这个代码是纯js不需要后端服务直接将两张电子发票的pdf转为两张图片渲染到一张A4纸上面&#xff08;完全不浪费&#xff0c;发票也不会变大&#xff09;&#xff0c;自动完成打印分页&#xff0c;点击打印即可。亲测可用所有电子发…...

第四百四十三回

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

一分钟快速用上号称“音乐版ChatGPT”的suno AI,适合普通人的超简单教程!

随着AI的应用变广&#xff0c;各类AI程序已逐渐普及。AI已逐渐深入到人们的工作生活方方面面。而AI涉及的行业也越来越多&#xff0c;从最初的写作&#xff0c;到医疗教育&#xff0c;再到现在的音乐。 Suno是一个专业高质量的AI歌曲和音乐创作平台&#xff0c;用户只需输入简…...

干货!一文读懂:位像素海外仓系统的分销功能

随着跨境电商的蓬勃发展&#xff0c;海外仓系统的重要性日益凸显&#xff0c;成为企业在激烈市场竞争中脱颖而出的关键。当谈及海外仓系统的拓展功能&#xff0c;特别是其中的分销功能&#xff0c;正逐渐成为卖家们不可或缺的工具。 那么&#xff0c;这个神奇的分销功能究竟是…...

【洛谷】P1449 后缀表达式

题目描述 所谓后缀表达式是指这样的一个表达式&#xff1a;式中不再引用括号&#xff0c;运算符号放在两个运算对象之后&#xff0c;所有计算按运算符号出现的顺序&#xff0c;严格地由左而右新进行&#xff08;不用考虑运算符的优先级&#xff09;。 本题中运算符仅包含 -*…...

【MySQL】聚合函数和分组聚合

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习计网、mysql和算法 ✈️专栏&#xff1a;MySQL学习 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac…...

RDD算子(四)、血缘关系、持久化

1. foreach 分布式遍历每一个元素&#xff0c;调用指定函数 val rdd sc.makeRDD(List(1, 2, 3, 4)) rdd.foreach(println) 结果是随机的&#xff0c;因为foreach是在每一个Executor端并发执行&#xff0c;所以顺序是不确定的。如果采集collect之后再调用foreach打印&#xf…...

51之定时器与中断系统

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

C语言中的内存函数

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

JS继承与原型、原型链

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

C#基础知识总结

C语言、C和C#的区别 ✔ 面向对象编程&#xff08;OOP&#xff09;&#xff1a; C 是一种过程化的编程语言&#xff0c;它不直接支持面向对象编程。然而&#xff0c;C 是一种支持 OOP 的 C 的超集&#xff0c;它引入了类、对象、继承、多态等概念。C# 是完全面向对象的&#xff…...

机器学习模型——决策树

决策树的定义&#xff1a; 决策树利用树形数据结构来展示决策规则和分类结果&#xff0c;它是一种归纳学习算法&#xff0c;可以将复杂数据转化为可以预测未知数据的模型。每一条从根节点到叶节点的路径都代表一条决策规则。 决策树内的一些重要名词&#xff1a; 信息熵&am…...

【HTML】制作一个简单的三角形动态图形

目录 前言 开始 HTML部分 CSS部分 效果图 总结 前言 无需多言&#xff0c;本文将详细介绍一段HTML和CSS代码&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建两个文本文档&#xff0c;其中HTML的文件名改为[index.html]&#xff0c;CSS的文件名…...

Acwing.504 转圈游戏(带取余的快速幂)

题目 n个小伙伴&#xff08;编号从 0到 n−1&#xff09;围坐一圈玩游戏。 按照顺时针方向给 n个位置编号&#xff0c;从 0到 n−1。 最初&#xff0c;第 0号小伙伴在第 0号位置&#xff0c;第 1号小伙伴在第 1号位置&#xff0c;…&#xff0c;依此类推。 游戏规…...

pair作为unordered_map的key报错

问题 pair作为unordered_map的key报错&#xff0c;编译时会报错 原因 因为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方法不是因为它是一个单例&#xff0c;而是因为这是创建DialogFragment实例并同时提供参数的一种标准模式。这种模式通常称为静态工厂方法模式&#xff0c;在Android开发中被广泛使用&#xff0c;尤其是用于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的时候给出例子答案&#xff0c;然后再让模型回答。 2、zero-shot-CoT “Let’s think step by step”有奇迹效果 3、多数投票提高CoT性能——自洽性&#xff08;Self-consistency&#xff09; 多个思维链&#xff0c;然后取…...

内网穿透的应用-如何在Android Termux上部署MySQL数据库并实现无公网IP远程访问

文章目录 前言1.安装MariaDB2.安装cpolar内网穿透工具3. 创建安全隧道映射mysql4. 公网远程连接5. 固定远程连接地址 前言 Android作为移动设备&#xff0c;尽管最初并非设计为服务器&#xff0c;但是随着技术的进步我们可以将Android配置为生产力工具&#xff0c;变成一个随身…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中&#xff0c;如何展示好看的实验结果图像非常重要&#xff01;&#xff01;&#xff01; 1、灰度原始图像 灰度图像每个像素点只有一个数值&#xff0c;代表该点的​​亮度&#xff08;或…...

GAN模式奔溃的探讨论文综述(一)

简介 简介:今天带来一篇关于GAN的,对于模式奔溃的一个探讨的一个问题,帮助大家更好的解决训练中遇到的一个难题。 论文题目:An in-depth review and analysis of mode collapse in GAN 期刊:Machine Learning 链接:...