使用fileinput+pdfbox获取pdf文档指定区域的内容

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/nb7474/article/details/80818156

本功能实现的思路如下:
1. 通过bootstrap-fileinput插件实现上传pdf文档
2. 通过pdfbox将pdf文档转换成图片格式,并保存在项目的根目录上。
3.访问根目录上的由pdf文档转成的图片,使用jquery-ui选取指定区域。
4.将指定区域的坐标x,y,width,heigth等信息传递到后台,按比例获取pdf文档上的指定区域的内容。
5.通过pdfbox解析指定区域的内容,并返回到前台进行展示。

1)fileinput+pdfbox的使用

一、下载安装

源码在github上共享,fileinout下载地址直接clone下来就可以了。
在html页面引入css文件夹的fileinput.min.css
引入js文件夹中的fileinput.min.js
引入locale文件夹下的zh.js

二、html页面

<div class="container">



        <form id="myForm">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title" id="myModalLabel">请选择PDF文件</h4>
                </div>
                <div class="modal-body">
                    <input type="file" name="txt_file" id="txt_file" 
                        class="file-loading" />
                </div>
            </div>
        </form>
    </div>
    <div id="picture" style="display: none">
        <button class="btn btn-default" onclick="getposition()">测量</button>
        <div id="box">
            <img src="" id="img1"> <img src="" id="img2">
            <div id="main">
                <div id="left-up" class="minDiv left-up"></div>
                <div id="up" class="minDiv up"></div>
                <div id="right-up" class="minDiv right-up"></div>
                <div id="right" class="minDiv right"></div>
                <div id="right-down" class="minDiv right-down"></div>
                <div id="down" class="minDiv down"></div>
                <div id="left-down" class="minDiv left-down"></div>
                <div id="left" class="minDiv left"></div>
            </div>
        </div>
        <div id="preview">
            <img src="" id="img3">
        </div>
    </div>

其中input标签是重点,multiple表示允许同时上传多个文件,class=“file-loading”表示标签的样式。这里很重要,如果class="file",则中文化不能生效。

这里写图片描述

三、js代码

$(function() {
        //0.初始化fileinput
        var oFileInput = new FileInput();
        oFileInput.Init("txt_file", "/api/OrderApi/ImportOrder");

    });
    var FileInput = function() {
        var oFile = new Object();

        //初始化fileinput控件(第一次初始化)
        oFile.Init = function(ctrlName, uploadUrl) {
            var control = $('#' + ctrlName);

            //初始化上传控件的样式
            control.fileinput({
                language : 'zh', //设置语言
                uploadUrl : 'uploadpdf', //上传的地址
                allowedFileExtensions : [ 'pdf', 'jpg', 'gif', 'png' ],//接收的文件后缀
                showUpload : true, //是否显示上传按钮
                showCaption : false,//是否显示标题
                browseClass : "btn btn-primary", //按钮样式     
                //dropZoneEnabled: false,//是否显示拖拽区域
                //minImageWidth: 50, //图片的最小宽度
                //minImageHeight: 50,//图片的最小高度
                //maxImageWidth: 1000,//图片的最大宽度
                //maxImageHeight: 1000,//图片的最大高度
                //maxFileSize: 0,//单位为kb,如果为0表示不限制文件大小
                //minFileCount: 0,
                maxFileCount : 10, //表示允许同时上传的最大文件个数
                enctype : 'multipart/form-data',
                validateInitialCount : true,
                previewFileIcon : "<i class='glyphicon glyphicon-king'></i>",
                msgFilesTooMany : "选择上传的文件数量({n}) 超过允许的最大数值{m}!",
            });

            //上传成功需要处理的内容。
            $("#txt_file").on("fileuploaded",
                    function(event, data, previewId, index) {
                        imgname=data.response.imgname;
                        filename=data.response.filename;
                        pdfheight=data.response.pdfheight;
                        pdfwidth=data.response.pdfwidth;
                        $("#box").height(pdfheight); //设置box的div的高度
                        $("#myForm").hide(500); //上传的表单隐藏
                        $("#picture").show(); //显示图片的div显示
                        $("#img1,#img2,#img3").attr("src",path+"/static/img/pdf/"+imgname); //将几个截
                                                            //取图片用到的图片标签的src路径指向后台传递过来的图片名
                    });
        }
        return oFile;
    };
    function getposition(){
        var imgwidth=$('#img1').width();
        var imgheight=$('#img1').height(); //获取图片的大小
        var x = $('#main').position().left*pdfwidth/imgwidth; 
        var y = $('#main').position().top*pdfheight/imgheight; 
        var width=$('#main').width()*pdfwidth/imgwidth;
        var height=$('#main').height()*pdfheight/imgheight;  //获取选区框的位置和宽度高度并按pdf文档的大小和图片的大小进行缩放
        console.log('x:'+x+'_y:'+y+'_width:'+width+'_height:'+height);
        var data={
                'x':x,
                'y':y,
                'width':width,
                'height':height,
                'filename':filename,
                'imgname':imgname
                };
        var jsonstring=JSON.stringify(data); //将各个参数的json对象转换成json字符串
        console.log(jsonstring);
        post('getpdftext', {"jsonstring" :jsonstring}); //调用post方法传递这些参数到后台
    }
function post(URL, PARAMS) {        
    var temp = document.createElement("form");        
    temp.action = URL;        
    temp.method = "post";        
    temp.style.display = "none";  
    temp.setAttribute('target', '_blank');
    for (var x in PARAMS) {        
        var opt = document.createElement("textarea");        
        opt.name = x;        
        opt.value = PARAMS[x];        
        // alert(opt.name)        
        temp.appendChild(opt);        
    }        
    document.body.appendChild(temp);        
    temp.submit();        
    return temp;        
}

说明:
* fileinput()方法里面传入的是一个json数据,它里面有很多属性,每个属性代表着初始化上传控件的时候的特性,如果这些属性都不设置,则表示使用默认的设置。如果园友们想看看它里面有哪些属性,可以打开fileinput.js的源码,在它的最后如图:

![](https://images2015.cnblogs.com/blog/459756/201511/459756-20151130164419483-421618128.png)

这些属性如果不特意设置,就会使用默认值。
  • $("#txt_file").on("fileuploaded", function (event, data, previewId, index) {}这个方法注册上传完成后的回调事件。也就是后天处理上传的文件之后进入这个方法里面处理。

    这里写图片描述

四、接收pdf上传的后台代码

@ResponseBody
    @RequestMapping("uploadpdf")
    public JSONObject pdfupload(@RequestParam MultipartFile[] txt_file,HttpServletRequest request) throws IOException{
        //如果只是上传一个文件,则只需要MultipartFile类型接收文件即可,而且无需显式指定@RequestParam注解   
        //如果想上传多个文件,那么这里就要用MultipartFile[]类型来接收文件,并且还要指定@RequestParam注解   
        //并且上传多个文件时,前台表单中的所有<input type="file"/>的name都应该是myfiles,否则参数里的myfiles无法获取到所有上传的文件   
        request.setCharacterEncoding("UTF-8");

        //如果用的是Tomcat服务器,则文件会上传到  {服务发布位置}\\WEB-INF\\upload\\文件夹中   
        String realPath = request.getSession().getServletContext().getRealPath("/WEB-INF/upload");
        String imgDir = request.getSession().getServletContext().getRealPath("/static/img/pdf");
        //这里不必处理IO流关闭的问题,因为FileUtils.copyInputStreamToFile()方法内部会自动把用到的IO流关掉,我是看它的源码才知道的   
        //FileUtils.copyInputStreamToFile(myfile.getInputStream(), new File(realPath, myfile.getOriginalFilename()));   
        String fileBname="";

        for (MultipartFile mFile : txt_file) {  
            String originalFileName= mFile.getOriginalFilename();//获取文件名称  
            String UUID = java.util.UUID.randomUUID().toString();  
            byte[] bytes = mFile.getBytes();//获取字节数组  
            fileBname = UUID+"."+mFile.getOriginalFilename().substring(mFile.getOriginalFilename().lastIndexOf(".")+1);
            File folder = new File(realPath);
            //文件夹路径不存在
            if (!folder.exists() && !folder.isDirectory()) {
                System.out.println("文件夹路径不存在,创建路径:" + realPath);
                folder.mkdirs();
            } else {
                System.out.println("文件夹路径存在:" + realPath);
            }

            // 如果文件不存在就创建
            File file = new File(realPath +File.separator+ fileBname);
            if (!file.exists()) {
                System.out.println("文件不存在,创建文件:" );
                FileOutputStream fos= new FileOutputStream(file); //写出到文件  
                fos.write(bytes);  
                fos.flush();  
                fos.close();
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("文件已存在,文件为:" + realPath + fileBname);
            }
        }  

        PdfUtil pdfUtil=new PdfUtil(realPath +File.separator+ fileBname);//获取pdf工具类对象,这个工具类是我自己写的

        String imgname=pdfUtil.getimgFrompdf(imgDir);//调用此工具类将指定目录的pdf转成图片,并赶回图片的name 
        float pdfwidth=pdfUtil.getpageWidth(0); //获取页面的宽度 用于后面与前面图片大小做比例缩放。
        float pdfheight=pdfUtil.getpageHeight(0); //获取页面的高度

        /*ModelAndView mv=new ModelAndView("/product/uploadsuccess");*/
        JSONObject json=new JSONObject();
        json.put("filename", fileBname);
        json.put("imgname", imgname);
        json.put("pdfwidth", pdfwidth);
        json.put("pdfheight", pdfheight);

        return json;
    }

其中MultipartFile是spring框架中提供的多文件上传工具,需要引入jar包:

<dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>

不同情况下属性的使用也不相同:
* 如果只是上传一个文件,则只需要MultipartFile类型接收文件即可,而且无需显式指定@RequestParam注解.
* 如果想上传多个文件,那么这里就要用MultipartFile[]类型来接收文件,并且还要指定@RequestParam注解
* 并且上传多个文件时,前台表单中的所有<input type="file"/>的name都应该是txt_file,否则参数里的txt_file无法获取到所有上传的文件。

通过request.getSession().getServletContext().getRealPath("/WEB-INF/upload");获取服务器上的upload文件夹,这个文件夹是用来存放上传的文件。

最后转换成图片选取的页面:
这里写图片描述

五、处理选取框的后台代码

@RequestMapping("getpdftext")
    public ModelAndView getPdfTextByRange(HttpServletRequest request,String jsonstring) throws IOException{

        String realPath = request.getSession().getServletContext().getRealPath("/WEB-INF/upload");

        System.out.println(jsonstring);

        JSONObject jsonObject=JSONObject.parseObject(jsonstring);//将json格式的字符串转换成json对象

        String fileName=jsonObject.getString("filename"); //获取json对象中的内容
        String imgname=jsonObject.getString("imgname");
        int pageNum=Integer.parseInt(imgname.substring(0,imgname.lastIndexOf(".")));//根据1.png类型的图片名获取页码

        PdfUtil pdfUtil=new PdfUtil(realPath+File.separator+fileName);//调用pdf工具类,需要传入pdf文件的路径

        PdfDoc pdfdoc=new PdfDoc(jsonObject.getIntValue("x"),
                                    jsonObject.getIntValue("y"),jsonObject.getIntValue("width"),
                                    jsonObject.getIntValue("height"),pageNum);//将属性绑定到pdfdoc的对象中


        PDDocument document=pdfUtil.getdocument();

        List<String> text=pdfUtil.getpageContent(document, pdfdoc);//传入参数获取指定区域的内容

        ModelAndView mv=new ModelAndView("/product/pdfcontent");
        mv.addObject("content",text);

        return mv;
    }

六、数据展示页面html

<div class="container" id="root">

        <ol>
            <c:forEach var="item" items="${content}"><li>${item}</li></c:forEach>
        </ol>
    </div>

最终数据展示:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/nb7474/article/details/80818156
今日推荐