前端pdf预览下载和图片下载、压缩

PDF文件预览

① 直接用 iframe 标签,体验较好,唯一不足滚动条样式没法自定义
【前端pdf预览下载和图片下载、压缩】② 用第三方插件,如 pdfjs
前端pdf预览下载和图片下载、压缩

下载PDF文件

在浏览器中直接用a标签模拟点击下载pdf文件,如果是跨域资源,浏览器会自动新开tab打开预览而不是下载,在网上找到几种解决方案:
① 在 pdf 资源路径后添加 ?response-content-type=application/octet-stream 参数
此种解决方案会将请求的资源当成二进制文件流,所以确实可以直接下载,但是如果路径是这样的格式:'https://xxx.com/HiheABZFpdf',下载的文件名会直接是 HiheABZFpdf,要自己手动在后面加上 .pdf才可以正常预览 。
② 用第三方插件 , 如:FileSaver
③ 用new XMLHttpRequest()发起请求转成二进制文件流 , 再本地下载
可以实现跨域下载,但资源服务器也要设置了可以跨域获取才可以 , 否则前端怎么做都是无用功:
function getBlob() {let xhr = new XMLHttpRequest()let _this = thisxhr.open('get', url, true)xhr.setRequestHeader('Content-Type', `application/pdf`)xhr.responseType = 'blob'xhr.onload = function() {if (this.status === 200) {// 接受二进制文件流// var blob = xhr.responsevar blob = this.response// 下载downloadExportFile(blob, '文件名', 'pdf')}}xhr.send()}function downloadExportFile(blobData, fileName, fileType = 'xlsx', callback) => {fileName = fileName'.'fileTypeif (window.navigator.msSaveOrOpenBlob) {// IE浏览器下navigator.msSaveBlob(blobData, fileName)} else {let link = document.createElement('a')link.href = https://www.itzhengshu.com/pdf/window.URL.createObjectURL(blobData)link.download = fileNamelink.click()window.URL.revokeObjectURL(link.href)}if (callback) {callback()}}
前端pdf预览下载和图片下载、压缩

跨域图片下载

直接用a标签下载 , 如果图片路径跨域浏览器也会自动打开而不是下载
① 绘制到 canvas 上再下载
function downImg (){let imgsrc = 'https://images.pexels.com/photos/11495860/pexels-photo-11495860.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260'let image = new Image()// 解决跨域image.setAttribute('crossOrigin', 'anonymous')image.src = https://www.itzhengshu.com/pdf/imgsrcimage.onload = function() {let canvas = document.createElement('canvas')canvas.width = image.widthcanvas.height = image.heightlet context = canvas.getContext('2d')context.drawImage(image, 0, 0, image.width, image.height)let url = canvas.toDataURL('image/png') // 得到图片的base64编码数据let a = document.createElement('a') // 生成一个a元素let event = new MouseEvent('click') // 创建一个单击事件a.download = '我的图片' // 设置图片名称a.href = https://www.itzhengshu.com/pdf/url // 将生成的URL设置为a.href属性a.dispatchEvent(event) // 触发a的单击事件}}
② 用new XMLHttpRequest()发起请求转成二进制文件流,再本地下载
这个和上面的pdf下载思路一样
function getBlob() {let xhr = new XMLHttpRequest()let _this = thisxhr.open('get', url, true)xhr.responseType = 'blob'xhr.onload = function() {if (this.status === 200) {// 接受二进制文件流// var blob = xhr.responsevar blob = this.response// 下载downloadExportFile(blob, '文件名', 'image/jpeg')}}xhr.send()}function downloadExportFile(blobData, fileName, fileType = 'xlsx', callback) => {fileName = fileName'.'fileTypeif (window.navigator.msSaveOrOpenBlob) {// IE浏览器下navigator.msSaveBlob(blobData, fileName)} else {let link = document.createElement('a')link.href = https://www.itzhengshu.com/pdf/window.URL.createObjectURL(blobData)link.download = fileNamelink.click()window.URL.revokeObjectURL(link.href)}if (callback) {callback()}}
前端pdf预览下载和图片下载、压缩

小程序base64图片下载

动态生成的小程序码需要后端去调用wx的接口,返回的是base64数据,前端实现下载代码:
function download() {// 此示例路径是一个无效路径let url = 'data:image/jpg;base64,eyJlcnJjb2RlIjo0ODAwMSwiZXJybXNnIjoiYXBpIHVuYXV0aG9yaXplZCByaWQ6IDYyNjY0ZTVkLTRkN2EyMTM4LTIyMzQzNDg2In0='let myBlob = this.dataURLtoBlob(url)let myUrl = URL.createObjectURL(myBlob)this.downloadFile(myUrl, '小程序码.png')}// 转 blobfunction dataURLtoBlob(dataurl) {let arr = dataurl.split(',')let mime = arr[0].match(/:(.*?);/)[1]let bstr = atob(arr[1])let n = bstr.lengthlet u8arr = new Uint8Array(n)while (n--) {u8arr[n] = bstr.charCodeAt(n)}return new Blob([u8arr], { type: mime })}function downloadFile(url, name = '小程序码') {let a = document.createElement('a')a.setAttribute('href', url)a.setAttribute('download', name)a.setAttribute('target', '_blank')let clickEvent = document.createEvent('MouseEvents')clickEvent.initEvent('click', true, true)a.dispatchEvent(clickEvent)}

图片压缩

利用canvas,先绘制到canvas上再实现压缩
function compressImage(file, success, error) => {// 图片小于1M不压缩if (file.size < Math.pow(1024, 2)) {return success(file)}const name = file.name // 文件名const reader = new FileReader()reader.readAsDataURL(file)reader.onload = e => {const src = https://www.itzhengshu.com/pdf/e.target.resultconst img = new Image()img.src = srcimg.onload = e => {const w = img.width / 1.5const h = img.height / 1.5const quality = 0.7 // 默认图片质量为0.92// 生成canvasconst canvas = document.createElement('canvas')const ctx = canvas.getContext('2d')// 创建属性节点const anw = document.createAttribute('width')anw.nodeValue = https://www.itzhengshu.com/pdf/wconst anh = document.createAttribute('height')anh.nodeValue = https://www.itzhengshu.com/pdf/hcanvas.setAttributeNode(anw)canvas.setAttributeNode(anh)// 铺底色 PNG转JPEG时透明区域会变黑色ctx.fillStyle ='#fff'ctx.fillRect(0, 0, w, h)ctx.drawImage(img, 0, 0, w, h)// quality值越小,所绘制出的图像越模糊const base64 = canvas.toDataURL('image/jpeg', quality) // 图片格式jpeg或webp可以选0-1质量区间// 去掉url的头,并转换为byteconst bytes = window.atob(base64.split(',')[1])// 处理异常,将ascii码小于0的转换为大于0const ab = new ArrayBuffer(bytes.length)const ia = new Uint8Array(ab)for (let i = 0; i < bytes.length; i) {ia[i] = bytes.charCodeAt(i)}let newFile = new File([ab], name, { type: 'image/jpeg' })success(newFile)}img.onerror = e => {error(e)}}reader.onerror = e => {error(e)}}

相关经验推荐