首页 > 其他分享 >js实现上传的pdf文件预览

js实现上传的pdf文件预览

时间:2023-06-14 09:56:19浏览次数:43  
标签:function canvas 预览 js current var pdf click

js实现pdf文件上传预览功能

需求: 上传预览功能, 支持图片和pdf上传预览, 并且是在指定的div里面预览

主要使用的是pdfjs库

pdfjs可以轻松实现点击打开一个新的页面或一个大的dialog在原页面实现预览, 但是不支持(可能是我没找到)在指定的div里面预览

这里要实现的是在指定的div里面预览

链接

  1. 依赖下载

    地址

    下载stable(v2.16.105)

    解压后在build目录下找到pdf.jspdf.work.js两个文件, copy到自己的项目

    使用了jquery方便dom操作

  2. 具体实现的功能:pdf上传显示, 上一页, 下一页

  3. 关键代码

    一个上传按钮, 点击时触发文件选择事件

    <button onclick="choosePdf()">选择一个pdf文件</button>
    <input style="display:none" id='chooseFile' type='file' accept="application/pdf">
     
    function choosePdf(){
     $("#chooseFile").click()
    }
    

    具体逻辑是在上传的change事件中实现的

    $("#uploadFile").change(function() {...})
    

    注意, 在网上找过很多版本, copy下来之后发现都有问题, 应该是pdfjs版本更新的问题, debugger了一下, 主要是两个地方:

     var loadingTask = pdfjsLib.getDocument(this.result)
    loadingTask.promise.then(function(pdf) {})
    
    // 这里 pdfjsLib.getDocument的参数是一个dataUrl, 直接使用上传的file是不行的
    //  pdfjsLib.getDocument里面包含一个promise对象, 之前的版本是直接 .then,  现在是.promise.then                    
    
    var viewport = page.getViewport({scale: scale})
    
    // 这里page.getViewport 的参数是一个对象形式, 之前的版本  可以直接传一个数字, 0.5 , 1,2  ,  现在如果直接数字的话, 获取的结果 height和 weight都是 NaN, 
    

    具体代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>pdf预览实现</title>
        <style>
            #container {
                width: 600px;
                height: 800px;
                margin-top: 5px;
                position: relative;
                border: 1px solid #333;
            }
            .commonBtn {
                position: absolute;
                width: 80px;
                height: 35px;
                line-height: 35px;
                text-align: center;
                background-color: #409eff;
                border-radius: 20px;
                color: #fff;
                cursor: pointer;
            }
            .commonBtn:hover {
                background-color: #66b1ff;
            }
            #pre {
                top: 20px;
                left: 20px;
            }
            #next {
                top: 20px;
                right: 20px;
            }
            #total {
                position: absolute;
                width: 50px;
                height: 30px;
                top: 20px;
                left: 50%;
                color: blueviolet;
            }
            #uploadBtn {
                display: inline-block;
                width: 80px;
                height: 35px;
                line-height: 35px;
                color: #fff;
                background-color: #67c23a;
                border-radius: 20px;
                cursor: pointer;
                text-align: center;
            }
            .forbid-click {
                background-color: #909399;
                cursor: not-allowed !important;
            }
            .forbid-click:hover {
                background-color: #909399 !important;
            }
            #fileName {
                color: aqua;
                margin-left: 20px;
            }
            #size {
                color: aquamarine;
                margin-left: 20px;
            }
        </style>
    </head>
    <body>
        <div id="opera_area">
            <span id="uploadBtn">选择文件</span>
            <span id="fileName"></span>
            <span id="size"></span>
            <input type="file" name="" id="uploadFile"  accept="application/pdf" style="display: none;">
        </div>
        <div id="container">
            <div id="pre" class="commonBtn forbid-click">上一页</div>
            <div id="next" class="commonBtn forbid-click">下一页</div>
            <div id="total" style="display: none;"><span id="currentPage"></span>/<span id="totalPage"></span></div>
        </div>
    
        <script src="js/jq.js"></script>
        <script src="js/pdf.js"></script>
        <script src="js/pdf.worker.js"></script>
        <script>
            var choosenFile = {}
            var total = 0
            var current = 0
            var scale = 1
            $(function() {
                $("#uploadBtn").click(function(e) {
                    $("#uploadFile").click()
                })
                $("#pre").click(function(e) {
                    if($("#pre").hasClass('forbid-click')) return
                    var currentCanvas = $('#canvas_' + current)
                    currentCanvas.hide()
                    $('#canvas_' + (current - 1)).show()
                    current -= 1
                    setPageState()
                })
                $("#next").click(function(e) {
                    if($("#next").hasClass('forbid-click')) return
                    var currentCanvas = $('#canvas_' + current)
                    currentCanvas.hide()
                    $('#canvas_' + (current + 1)).show()
                    current += 1
                    setPageState()
                })
                function setPageState() {
                    setCurPage()
                    if(current <= 1) {
                        $("#pre").addClass('forbid-click')
                    } else {
                        $("#pre").removeClass('forbid-click')
                    }
                    if(current >= total) {
                        $("#next").addClass('forbid-click')
                    } else {
                        $("#next").removeClass('forbid-click')
                    }
                }
                function setCurPage() {
                    $('#currentPage').text(current)
                    $('#totalPage').text(total)
                }
                function renderCanvas(pdf, i, canvas) {
                    var outputScale = window.devicePixelRatio || 1
                    pdf.getPage(i).then(function(page) {
                    var viewport = page.getViewport({scale: scale})
                    var context = canvas.getContext('2d')
                    canvas.width = Math.floor(viewport.width * outputScale)
                    canvas.height = Math.floor(viewport.height * outputScale)
                    canvas.style.width = Math.floor(viewport.width) + 'px'
                    canvas.style.height = Math.floor(viewport.height) + 'px'
                    var transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0]: null
                    var renderContext = {
                        canvasContext: context,
                        transform: transform,
                        viewport: viewport
                    }
                    if(i != 1) {
                        canvas.style.display = 'none'
                    }
                    page.render(renderContext)
                })
                }
                $("#uploadFile").change(function(e) {
                    var file = e.target.files[0]
                    if(file.size > 5 * 1024 * 1024) {
                        return alert('上传文件大于5M')
                    }
                    $("#container canvas").remove()
                    $('#total').show()
                    current = 1
                    choosenFile.fileName = file.name
                    choosenFile.size = (file.size/(1024 * 1024)).toFixed(2)
                    choosenFile.file = file
                    $("#fileName").text(choosenFile.fileName)
                    $("#size").text(choosenFile.size + 'MB')
    
                    var reader = new FileReader()
                    reader.readAsDataURL(file)
                    reader.onload = function(e) {
                        // getDocument的参数是一个dataUrl
                        var loadingTask = pdfjsLib.getDocument(this.result)
                        loadingTask.promise.then(function(pdf) {
                            if(pdf) {
                                total = pdf.numPages
                                current = 1
                                setCurPage()
                                setPageState()
                            }
                            for(var i = 1; i <= total; i ++) {
                                var canvas = document.createElement('canvas')
                                canvas.id = 'canvas_' + i
                                $("#container").append(canvas)
                                // 这里封装成一个方法, 不能散装在这里, 因为异步会有问题
                                renderCanvas(pdf, i, canvas)
                            }
                        })
                    }
    
                })
            })
        </script>
    </body>
    </html>
    

    实现的效果

    image-20221010164253578

标签:function,canvas,预览,js,current,var,pdf,click
From: https://www.cnblogs.com/littlelittleship/p/16776316.html

相关文章

  • Three.js教程:三维坐标系
    推荐:将NSDT场景编辑器加入你的3D工具链其他系列工具:NSDT简石数字孪生三维坐标系本节课的目的就是为了加强大家对threejs三维空间的认识。辅助观察坐标系THREE.AxesHelper()的参数表示坐标系坐标轴线段尺寸大小,你可以根据需要改变尺寸。//AxesHelper:辅助观察的坐标系const......
  • 再也不用担心变量类型错误!学会JS中如何轻松检查变量类型
    今天要分享的问题就是:如何在JS中检查一个变量的类型?先上结论:如果判断的是基本数据类型或JavaScript内置对象,使用toString;如果要判断的是自定义类型,请使用instanceof。在ECMAScript规范中,共定义了7种数据类型,分为基本类型和引用类型两大类。基本类型也称为简单类型,按......
  • json字符串解析 多语言替换
    importlombok.extern.slf4j.Slf4j;importorg.apache.commons.collections4.MapUtils;importorg.apache.commons.lang3.StringUtils;importorg.springframework.beans.factory.annotation.Value;importjava.util.HashSet;importjava.util.List;importjava.util.M......
  • 模块(os、json、pickle)
    os模块主要与操作系统打交道,是与操作系统交互的一个窗口1.os.mkdir('dirname')创建单级目录dirname2.os.makedirs('dirname1/dirname2')生成多层递归目录dirnmae1下的dirname23.os.rmdir('dirname')删除空白单级目录dirname,若dirname不为空则无法删除,并报错 ......
  • js Math
    JavaScript中的Math对象是一个数学库,提供了许多数学函数和常量,可以用于进行各种数学计算和运算。以下是Math对象的一些常用属性和方法:常量:Math.PI:圆周率。Math.E:自然对数的底数。数学函数:Math.abs(x):返回x的绝对值。Math.ceil(x):返回大于或等于x的最小整数。Math.fl......
  • post、raw、json调用第三方接口
    1、调用第三方接口,对方接口文档写到”请求方式postjson格式、请求参数json格式“,看不懂,就用postMan试试看。发现只有一种方式能调用通, 2、 3、Content-Type:application/json  4、根据上面的方式,所有写了下面的方法:/****@paramurl接口地址*@paramputData......
  • JavaCV音视频开发宝典:使用JavaCV读取海康平台或海康网络摄像头sdk回调视频TS码流并解
    《JavaCV音视频开发宝典》专栏目录导航《JavaCV音视频开发宝典》专栏介绍和目录​前言两年前博主写了如何利用JavaCV解析各种h264裸流,《JavaCV音视频开发宝典:使用javacv读取GB28181、海康大华平台和网络摄像头sdk回调视频码流并解析预览图像》,但是随着时间变化,各个厂商sdk也......
  • JS-数组和函数
    1.数组数组Array:是一种可以按顺序保存数据的数据类型1.1声明数组let数组名=[数据1,数据2,数据3,...,数据n]或let数组名=newArray(数据1,数据2,数据3,...,数据n)<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahtt......
  • package.json中的版本号
    NPM的语义版本控制在发布NPM模块新版本时,建议遵循“语义版本控制”考虑使用这样的版本号x.y.z控制,如下所示:版本号规则:主版本:做了不兼容的API修改,不会向前兼容,一般也称为大版本,当项目依赖需要升级到大版本时需要注意。次版本:通常是做了向前兼容的新功能增加,一般也称为......
  • idea 配置tomcat 运行jsp项目
    1、复用idea打开jsp项目2、添加tomcat配置3、点击后会出现配置框,这里画框的地方都选上,版本选择1.8,其他的信息内容默认后,点击确认4、点击File->ProjectStructure,弹出界面选择Project,这里sdk选择1.8,语言选择85、选择Modules,右击项目名称-》选择Add-》选择Web6、配置Modules,选......