一、背景

  最近公司一个项目要实现一个文件上传以及多文档在线预览的功能,之前一直做无线工具开发的,没有涉及到这些东西。另外项目组缺java开发人员,而且自己也只是一个半吊子前端加小半吊子java开发人员,所以让我一个人先弄个Demo出来瞧瞧。在网上搜索了不少资料,在这里只是整理一下,留作以后查阅。

二、插件以及工具包

  1.pdfjs-v1.7.225  前端pdf格式文件的显示组件

  2.webuploader-0.1.5  百度的文件上传组件

  3.video-js-6.2.5 html5视频播放组件

  4.openoffice-4.1.3 本地安装的,这里主要用于文档转pdf的程序

  5.jodconverter-core 3.0-beta-4 java调用openoffice的包

  其中pdfjs可以用ViewerJS来代替,后者相对于是对前者的封装。另外java包jodconverter也可以用com.artofsolving.jodconverter.2.2.1来代替,根据网上别人说的以及自己小小测试了一下jodconverter.2.2.1也转换pdf的时候要快那么一点点,但是却不支持office2003之后的docx/xlsx/pptx这些文件类型,说是要定制java代码也可以实现支持,本来比较懒也就弃用了。

三、代码

  废话说了一大堆先上前端代码,由于是Demo,代码写的很糙;

  1.主要页面index.html 

1 <!DOCTYPE html>
2 <htmllang="en">
3 <head>
4     <metacharset="UTF-8">
5     <metaname="viewport"content="width=device-width, initial-scale=1.0">
6     <metahttp-equiv="X-UA-Compatible"content="ie=edge">
7     <title>文件预览Demo</title>
8     <!--jquery-->
9     <scriptsrc="./plugIns/jquery-3.2.1.min.js"></script>
10     <!--bootstrap-->
11     <linkrel="stylesheet"href="./plugIns/bootstrap-3.3.7/css/bootstrap.min.css">
12     <scriptsrc="./plugIns/bootstrap-3.3.7/js/bootstrap.min.js"charset="utf-8"></script>
13     <!--webuploader-->
14     <linkrel="stylesheet"type="text/css"href="./plugIns/webuploader-0.1.5/webuploader.css">
15     <scripttype="text/javascript"src="./plugIns/webuploader-0.1.5/webuploader.min.js"></script>
16     <!--font-awesome-->
17     <linkrel="stylesheet"href="./plugIns/font-awesome-4.7.0/css/font-awesome.min.css">
18     <linkrel="stylesheet"href="./css/filepreview/preview.css">
19 </head>
20
21 <body>
22     <divclass="container"style="padding-top:150px;">
23         <div>
24             <divclass="list">
25
26             </div>
27         </div>
28         <divid="uploader"class="wu-example">
29             <!--用来存放文件信息-->
30             <divid="thelist"class="uploader-list"></div>
31             <divclass="btns">
32                 <divid="picker">选择文件</div>
33                 <buttonid="ctlBtn"class="btn btn-default">开始上传</button>
34             </div>
35         </div>
36     </div>
37     <divclass="load">
38         <imgsrc="./images/loading.gif"alt="">
39     </div>
40 </body>
41 <scriptsrc="./js/filepreview/preview.js"charset="utf-8"></script>
42 <scriptsrc="./js/filepreview/upload.js"charset="utf-8"></script>
43 </html>

  2.控制文件上传的upload.js

1 $(function() {2     var $list = $('#thelist'),3         $btn = $('#ctlBtn'),4         state = 'pending';5     var uploader =WebUploader.create({6         //swf文件路径
7         swf: './plugIns/webuploader-0.1.5/Uploader.swf',8         //文件接收服务端。
9         server: '/file/upload',10         //选择文件的按钮。可选。
11         //内部根据当前运行是创建,可能是input元素,也可能是flash.
12         pick: '#picker',13         //不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
14         resize: false,15         //开起分片上传。
16         chunked: true,17         //fileSingleSizeLimit: 10*1024*1024,//限制大小10M,单文件
18         //fileSizeLimit: allMaxSize*1024*1024,//限制大小10M,所有被选文件,超出选择不上
19         //设置允许上传的文件类型,不过点击选择文件的时候会很卡
20         //accept: {
21         //title: 'Images',
22         //extensions: 'jpg,png',
23         //mimeTypes: 'image/*'
24         //}
25 });26     //当有文件被添加进队列的时候
27     uploader.on('fileQueued', function(file) {28         let typeList = ['png', 'jpg', 'txt', 'xls', 'doc', 'ppt', 'pdf', 'mp4','docx','pptx','xlsx'];29         if(!typeList.includes(file.name.split('.')[1])){30             alert("不支持的文件类型!");31 uploader.removeFile( file );32             return;33 }34
35
36         $list.append('<div id="' + file.id + '" class="item">' +
37             '<h4 class="info">' + file.name + '</h4>' +
38             '<p class="state">等待上传...</p>' +
39             '</div>');40 });41     //文件上传过程中创建进度条实时显示。
42     uploader.on('uploadProgress', function(file, percentage) {43         var $li = $('#' +file.id),44             $percent = $li.find('.progress .progress-bar');45
46         //避免重复创建
47         if (!$percent.length) {48             $percent = $('<div class="progress progress-striped active">' +
49                 '<div class="progress-bar" role="progressbar" style="width: 0%">' +
50                 '</div>' +
51                 '</div>').appendTo($li).find('.progress-bar');52 }53
54         $li.find('p.state').text('上传中');55
56         $percent.css('width', percentage * 100 + '%');57 });58     uploader.on('uploadSuccess', function(file) {59 getFileList();60         $('#' + file.id).find('p.state').text('已上传');61 });62
63     uploader.on('uploadError', function(file) {64         $('#' + file.id).find('p.state').text('上传出错');65 });66
67     uploader.on('uploadComplete', function(file) {68         $('#' + file.id).find('.progress').fadeOut();69 });70
71     uploader.on('all', function(type) {72         if (type === 'startUpload') {73             state = 'uploading';74         } else if (type === 'stopUpload') {75             state = 'paused';76         } else if (type === 'uploadFinished') {77             state = 'done';78 }79
80         if (state === 'uploading') {81             $btn.text('暂停上传');82         } else{83             $btn.text('开始上传');84 }85 });86
87     $btn.on('click', function() {88         if (state === 'uploading') {89 uploader.stop();90         } else{91 uploader.upload();92 }93 });94 });

  3.负责预览的preview.js

1 $(function() {2     const typeList = ['png', 'jpg', 'txt', 'xls', 'doc', 'ppt', 'pdf','docx','pptx','xlsx'];3     getFileList = function() {4         $(".list").empty();5         $.get("/file/list", function(data) {6             data =JSON.parse(data);7             for(let file of data) {8                 let htmlStr = '<a class="point file" data-file="' + file.name + '" data-size="' + file.size + '" data-type="'+ file.type +'">';9                 if (file.type.toLowerCase() == 'png' || file.type.toLowerCase() == 'jpg') {10                     htmlStr = '<a class="file" target="_blank" href="./filelist/' + file.name + '">';11                 } else if (file.type.toLowerCase() == 'pdf') {12                     htmlStr = '<a class="file" target="_blank" href="http://localhost:8080/plugIns/pdfjs/web/viewer.html?file=../../../../filelist/' + file.name + '">';13                 } else if (file.type.toLowerCase() == 'mp4') {14                     htmlStr = '<a class="file" target="_blank" href="video?path=../../filelist/' + file.name + '">';15 }16                 let imgName = file.type=='docx'||file.type=='xlsx'||file.type=='pptx'?file.type.substr(0,file.type.length-1):file.type;17                 $(".list").append(18                     '<div class="col-xs-6 col-md-2">' + htmlStr +
19                     '<embed src="./images/svg/' + imgName + '.svg" type="image/svg+xml" /><span>' + file.name +
20                     '</span></a>&nbsp;<i class="fa fa-eye"></i>&nbsp;<span class="number">'+file.number+'</span></div>'
21 );22 }23 });24 }25 getFileList();26
27     /**28 * 无法直接查看的文件,需要server先进行转换29      */
30     $(".list").on("click", ".point", function() {31         let date = newDate().getTime();32         let param = $(this).data("file");33         let type = $(this).data("type");34         if (typeList.indexOf(type)==-1) {35             alert("暂不支持预览的文件类型!");36             return;37 }38         if ($(this).data("size") >= 11534336) {39             alert("文件太大,暂不支持预览!");40             return;41 }42         $('.load').addClass('active');43 $.ajax({44             type: 'post',45             url: '/file/preview',46 data: param,47             contentType: 'application/json',48             dataType: 'text',49             success: function(data) {50                 $('.load').removeClass('active');51                 console.log("转换耗时===>" + (new Date().getTime() - date) + "ms");52                 window.open("http://localhost:8080/plugIns/pdfjs/web/viewer.html?file=../../../../filelist/temp/" + data + ".pdf");53 },54             error: function(error) {55                 $('.load').removeClass('active');56                 alert("error!");57 }58 });59 });60
61     /**62 * 查看文件,浏览量累加63      */
64     $(".list").on("click", ".file", function() {65         let nSpan = $(this).parent().find('.number');66         nSpan.text(nSpan.text()/1+1);
67 });68 });

  4.播放mp4格式的video.html

1 <!DOCTYPE html>
2 <htmllang="en">
3
4 <head>
5     <metacharset="UTF-8">
6     <metaname="viewport"content="width=device-width, initial-scale=1.0">
7     <metahttp-equiv="X-UA-Compatible"content="ie=edge">
8     <title></title>
9     <linkrel="stylesheet"href="/plugIns/video-js-6.2.5/video-js.min.css">
10     <!--If you'd like to support IE8-->
11     <scriptsrc="/plugIns/jquery-3.2.1.min.js"></script>
12     <scriptsrc="/plugIns/video-js-6.2.5/ie8/videojs-ie8.min.js"charset="utf-8"></script>
13     <scriptsrc="/Global.js"charset="utf-8"></script>
14     <stylemedia="screen">
15 .videoCont{
16 padding-top:150px;
17         }
18     </style>
19 </head>
20
21 <body>
22     <divclass="videoCont">
23         <videoid="my-video"class="video-js"controls preload="auto"width="720"height="480"poster="MY_VIDEO_POSTER.jpg"data-setup="{}">
24             <sourcesrc="http://vjs.zencdn.net/v/oceans.mp4"type="video/mp4">
25             <!--<source src="http://vjs.zencdn.net/v/oceans.webm" type="video/webm">26 <source src="/filelist/Wildlife.wmv" type="video/wmv">-->
27             <pclass="vjs-no-js">
28 To view this video please enable JavaScript, and consider upgrading to a web browser that29                 <ahref="http://videojs.com/html5-video-support/"target="_blank">supports HTML5 video</a>
30             </p>
31         </video>
32     </div>
33     <scriptsrc="/plugIns/video-js-6.2.5/video.min.js"charset="utf-8"></script>
34     <scripttype="text/javascript">
35 let wWidth=document.body.clientWidth;36 $('.videoCont').css('padding-left',(wWidth-$('#my-video').attr("width"))/2);
37 let path=Global.getParamByKey("path");38 $("#my-video source[type='video/mp4']").attr("src",path);39         varmyPlayer=videojs('my-video');40 videojs("my-video").ready(function() {41             varmyPlayer= this;42 myPlayer.play();43 });44     </script>
45 </body>
46
47 </html>

  5.pom.xml

1 <dependencies>
2         <!--Spring Boot web依赖-->
3         <dependency>
4             <groupId>org.springframework.boot</groupId>
5             <artifactId>spring-boot-starter-web</artifactId>
6         </dependency>
7
8         <!--Junit-->
9         <dependency>
10             <groupId>junit</groupId>
11             <artifactId>junit</artifactId>
12             <version>4.12</version>
13         </dependency>
14         <dependency>
15             <groupId>org.apache.commons</groupId>
16             <artifactId>commons-lang3</artifactId>
17             <version>3.6</version>
18         </dependency>
19         <!--openoffice-->
20         <dependency>
21             <groupId>org.quartz-scheduler</groupId>
22             <artifactId>quartz</artifactId>
23             <version>2.3.0</version>
24         </dependency>
25         <!--不支持03之后的office-->
26         <dependency>
27             <groupId>com.artofsolving</groupId>
28             <artifactId>jodconverter</artifactId>
29             <version>2.2.1</version>
30         </dependency>
31         <!--支持03之后的office-->
32         <dependency>
33             <groupId>org.artofsolving.jodconverter</groupId>
34             <artifactId>jodconverter-core</artifactId>
35             <version>3.0-beta-4</version>
36         </dependency>
37         <dependency>
38             <groupId>org.openoffice</groupId>
39             <artifactId>jurt</artifactId>
40             <version>3.0.1</version>
41         </dependency>
42         <dependency>
43             <groupId>org.openoffice</groupId>
44             <artifactId>ridl</artifactId>
45             <version>3.0.1</version>
46         </dependency>
47         <dependency>
48             <groupId>org.openoffice</groupId>
49             <artifactId>juh</artifactId>
50             <version>3.0.1</version>
51         </dependency>
52         <dependency>
53             <groupId>org.openoffice</groupId>
54             <artifactId>unoil</artifactId>
55             <version>3.0.1</version>
56         </dependency>
57
58         <!--jodconverter2.2.1必须依赖slf4j-jdk14必须这个版本,不然源码中日志会报错,很low的一个问题-->
59         <dependency>
60             <groupId>org.slf4j</groupId>
61             <artifactId>slf4j-jdk14</artifactId>
62             <version>1.4.3</version>
63         </dependency>
64
65         <!--https://mvnrepository.com/artifact/com.alibaba/fastjson-->
66         <dependency>
67             <groupId>com.alibaba</groupId>
68             <artifactId>fastjson</artifactId>
69             <version>1.2.35</version>
70         </dependency>
71
72         <dependency>
73             <groupId>commons-fileupload</groupId>
74             <artifactId>commons-fileupload</artifactId>
75             <version>1.3.1</version>
76         </dependency>
77     </dependencies>

  6.文档转pdf格式的工具类Office2PdfUtil

1 packageorg.spring.springboot.util;2
3 importjava.io.File;4 importjava.util.regex.Pattern;5
6 importorg.artofsolving.jodconverter.OfficeDocumentConverter;7 importorg.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;8 importorg.artofsolving.jodconverter.office.OfficeManager;9
10 public classOffice2PdfUtil {11
12     private static Office2PdfUtil office2PdfUtil = newOffice2PdfUtil();13     private staticOfficeManager officeManager;14     //服务端口
15     private static int OPEN_OFFICE_PORT[] = { 8100, 8101, 8102, 8103};16
17     public staticOffice2PdfUtil getOffice2PdfUtil() {18         returnoffice2PdfUtil;19 }20
21     /**
22 *23 * office2Pdf 方法24 *25 * @descript:TODO26 *@paraminputFile27 *            文件全路径28 *@parampdfFilePath29 *            pdf文件全路径30 *@returnvoid31      */
32     public static voidoffice2Pdf(File inputFile, File pdfFile) {33
34         try{35             //打开服务36             startService();
37             OfficeDocumentConverter converter = newOfficeDocumentConverter(officeManager);38             //开始转换
39 converter.convert(inputFile, pdfFile);40             //关闭41             stopService();
42             System.out.println("运行结束");43         } catch(Exception e) {44             //TODO: handle exception
45 e.printStackTrace();46 }47 }48
49     public static voidstopService() {50         if (officeManager != null) {51 officeManager.stop();52 }53 }54
55     public static voidstartService() {56         DefaultOfficeManagerConfiguration configuration = newDefaultOfficeManagerConfiguration();57         try{58             configuration.setOfficeHome(getOfficeHome());//设置安装目录
59             configuration.setPortNumbers(OPEN_OFFICE_PORT); //设置端口
60             configuration.setTaskExecutionTimeout(1000 * 60 * 5L);61             configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);62             officeManager =configuration.buildOfficeManager();63             officeManager.start(); //启动服务
64         } catch(Exception ce) {65             System.out.println("office转换服务启动失败!详细信息:" +ce);66 }67 }68
69     /**
70 * openoffice的安装路径71 *72 *@return
73      */
74     public staticString getOfficeHome() {75         String osName = System.getProperty("os.name");76         if (Pattern.matches("Linux.*", osName)) {77             return "/opt/openoffice.org3";78         } else if (Pattern.matches("Windows.*", osName)) {79             return "C:/Program Files (x86)/OpenOffice 4/";80         } else if (Pattern.matches("Mac.*", osName)) {81             return "/Application/OpenOffice.org.app/Contents";82 }83         return null;84 }85 }

  这里需要注意的是不需要手动去开启系统中的openoffice,以上代码运行的时候会自动开启。

  private static int OPEN_OFFICE_PORT[] = { 8100, 8101, 8102, 8103 }; 这个是openoffice的端口,默认是 {8100} ,写入多个是为了开启多个Openoffice服务,加快多线程转换的效率。    7.接口类FileController
1 packageorg.spring.springboot.web;2
3 importjava.io.File;4 importjava.io.IOException;5 importjava.util.ArrayList;6 importjava.util.Iterator;7
8 importjavax.servlet.http.HttpServletRequest;9 importjavax.servlet.http.HttpServletResponse;10
11 importorg.spring.springboot.bean.FileBean;12 importorg.spring.springboot.util.Office2PdfUtil;13 importorg.springframework.web.bind.annotation.GetMapping;14 importorg.springframework.web.bind.annotation.PostMapping;15 importorg.springframework.web.bind.annotation.RequestBody;16 importorg.springframework.web.bind.annotation.RequestMapping;17 importorg.springframework.web.bind.annotation.RestController;18 importorg.springframework.web.multipart.MultipartFile;19 importorg.springframework.web.multipart.MultipartHttpServletRequest;20 importorg.springframework.web.multipart.commons.CommonsMultipartResolver;21
22 importcom.alibaba.fastjson.JSON;23
24
25 @RestController26 @RequestMapping("file")27 public classFileController {28
29     @GetMapping("list")30     publicString getFileList() {31         returngetFileName();32 }33
34     public staticString getFileName() {35         String path = System.getProperty("user.dir") + "\\src\\main\\resources\\static\\filelist"; //路径
36         File f = newFile(path);37         if (!f.exists()) {38             System.out.println(path + " not exists");39             return null;40 }41
42         ArrayList<FileBean> files = new ArrayList<>();43
44         File fa[] =f.listFiles();45         for(File fs : fa) {46             if(fs.isFile()) {47                 FileBean fb = new FileBean(fs.getName(), fs.getName().split("\\.")[1], String.valueOf(fs.length()));48 files.add(fb);49 }50 }51         returnJSON.toJSONString(files);52 }53
54     @PostMapping(value = "preview", produces = "application/json; charset=utf-8")55     public String getPreview(@RequestBody String fileName) throwsIOException {56         String sysDir = System.getProperty("user.dir") + "\\src\\main\\resources\\static\\filelist\\";57         File inputFile = new File(sysDir +fileName);58         String outputPath = sysDir + "temp";59         File temp = newFile(outputPath);60         //目录不存在,创建目录
61         if (!temp.exists()) {62 temp.mkdir();63 }64         File outputFile = newFile(65                 outputPath + "\\" + fileName.split("\\.")[0] + "_" + fileName.split("\\.")[1] + ".pdf");66         //如果转换后的文件已经存在那么不需要再次转换
67         if(outputFile.exists()) {68             return fileName.split("\\.")[0]+ "_" + fileName.split("\\.")[1];69 }70         //方法一:用com.artofsolving71         //OpenOfficeUtil.office2Pdf(inputFile, outputFile);72         //方法二:用org.artofsolving
73 Office2PdfUtil.office2Pdf(inputFile, outputFile);74         return fileName.split("\\.")[0]+ "_" + fileName.split("\\.")[1];75 }76
77     @RequestMapping("/upload")78     publicString upload2(HttpServletRequest request, HttpServletResponse response)79             throwsIllegalStateException, IOException {80         //创建一个springmvc上传文件解析器
81         CommonsMultipartResolver multipartResolver = newCommonsMultipartResolver();82         //判断 request 是否有文件上传,即多部分请求
83         if(multipartResolver.isMultipart(request)) {84             //转换成多部分request
85             MultipartHttpServletRequest multiRequest =(MultipartHttpServletRequest) request;86             //取得request中的所有文件名
87             Iterator<String> iter =multiRequest.getFileNames();88             while(iter.hasNext()) {89                 //记录上传过程起始时的时间,用来计算上传时间
90                 int pre = (int) System.currentTimeMillis();91                 //取得上传文件
92                 MultipartFile file =multiRequest.getFile(iter.next());93                 if (file != null) {94                     //取得当前上传文件的文件名称
95                     String myFileName =file.getOriginalFilename();96                     //如果名称不为“”,说明该文件存在,否则说明该文件不存在
97                     if (myFileName.trim() != "") {98 System.out.println(myFileName);99                         //重命名上传后的文件名100                         //String fileName = "demoUpload" + file.getOriginalFilename();101                         //定义上传路径
102                         String path = System.getProperty("user.dir") + "\\src\\main\\resources\\static\\filelist\\"
103                                 +myFileName;104                         File localFile = newFile(path);105                         try{106 file.transferTo(localFile);107                         } catch(IOException e) {108 e.printStackTrace();109 }110 }111 }112                 //记录上传该文件后的时间
113                 int finaltime = (int) System.currentTimeMillis();114                 System.out.println(finaltime -pre);115 }116 }117         return "/success";118 }119 }

  8.最后一个和Demo没有关系,完全就是一个多线程转换pdf的一个测试

1 packageorg.spring.springboot;2
3 importjava.io.File;4 importjava.net.ConnectException;5 importjava.util.concurrent.CountDownLatch;6
7 importorg.spring.springboot.util.Office2PdfUtil;8 importorg.spring.springboot.util.OpenOfficeUtil;9
10 public class Main extendsThread {11     private intindex;12     privateCountDownLatch latch;13
14     public Main(intindex, CountDownLatch latch) {15         this.index =index;16         this.latch =latch;17 }18
19 @Override20     public voidrun() {21         super.run();22         String str = String.format("5m_%s.doc", index);23         long time =System.currentTimeMillis();24 work(str);25 latch.countDown();26         System.out.println(String.format("文件%s解析耗时:%sms", str, String.valueOf(System.currentTimeMillis() -time)));27 }28
29     public static voidmain(String[] args) {30         CountDownLatch latch = new CountDownLatch(50);31 Office2PdfUtil.startService();32         for (int i = 1; i < 51; i++) {33             newMain(i, latch).start();34 }35         try{36             long time =System.currentTimeMillis();37             System.out.println(String.format("开始"));38 latch.await();39 Office2PdfUtil.stopService();40             System.out.println(String.format("所有文件解析耗时:%sms", String.valueOf(System.currentTimeMillis() -time)));41         } catch(InterruptedException e) {42             //TODO Auto-generated catch block
43 e.printStackTrace();44 }45 }46
47     public static voidwork(String fileName) {48         String sysDir = System.getProperty("user.dir") + "\\src\\main\\resources\\static\\test\\";49         File inputFile = new File(sysDir +fileName);50         String outputPath = sysDir + "temp";51         File outputFile = newFile(52                 outputPath + "\\" + fileName.split("\\.")[0] + "_" + fileName.split("\\.")[1] + ".pdf");53 Office2PdfUtil.office2Pdf(inputFile, outputFile);54 }55
56 }

  CountDownLatch可以监测多线程运行结束。第30、32行的数字是设置解析的文件数量。    9.python生成多个有内容的文件代码也一并奉上
1 #-*-coding:utf-8-*-
2 defgen_file(path,size):3     #首先以路径path新建一个文件,并设置模式为写
4     file = open(path,'w')5     #根据文件大小,偏移文件读取位置
6     file.seek(1024*1024*size)#姑且以MB为单位吧
7     #然后在当前位置写入任何内容,必须要写入,不然文件不会那么大哦
8     file.write('\x00')9 file.close()10
11
12
13 for i in range(100):14     gen_file('E:/5m_'+str(i+1)+'.doc',5)  

以上都是测试代码,项目中这么写是要挨批的。完全是为了做个笔记,免得下次又要到处找。

四、页面

这里面坑确实不少,不过我觉得主要在于pdf转换这一步:1.jodconverter-core 3.0-beta-4 这个包的maven依赖貌似下载不了2.com.artofsolving.jodconverter与org.artofsolving.jodconverter这两个包傻傻分不清3.openoffice免费的嘛,你懂得,转换效率不敢恭维,慢得很,而且并发支持并不好4.用com.artofsolving.jodconverter的话转换几十个文件,动不动就没有规律的会卡着不动,等半个小时依然没有反应,必须杀掉openoffice进程才能重来,试了很多次,org.artofsolving.jodconverter没有发现这个问题。5.多个文档转换的时候,打开openoffice服务和关闭openoffice服务都只需要调用一次。不然每次都开开关关的很无语。

 

转载于:https://www.cnblogs.com/jjdw/p/jjdw_blog_001.html

用openoffice+jodconverter+webuploader+pdf.js实现文件上传、在线预览功能相关推荐

  1. js html怎么加入图片,js实现图片上传并预览功能

    思路:完成这个功能,首先需要美化上传图片的按钮,然后添加一个 标签,在图片上传之后,用新图片的src替换原来 标签中的src. 如下图所示,是原始的按钮样式: 美化步骤: (1)将上传图片标签采用绝对 ...

  2. php案例 文件上传并预览

    作者:陈业贵 华为云享专家 51cto(专家博主 明日之星 TOP红人) 阿里云专家博主 文章目录 前言 代码 cyg.php 2.php 效果:也就是上传的文件里面的内容 前言 php案例 文件上传 ...

  3. uploadify java 下载_uploadify java实现多文件上传和预览

    本文实例为大家分享了java文件上传和预览实现代码,供大家参考,具体内容如下 1.下载uploadify插件 2.index.html #uploader { position: relative; ...

  4. php 表格导入excel插件,BootStrap Fileinput插件和表格插件相结合实现导入Excel数据的文件上传、预览、提交的步骤...

    这篇文章主要介绍了BootStrap Fileinput插件和Bootstrap table表格插件相结合实现文件上传.预览.提交的导入Excel数据操作步骤,需要的朋友可以参考下 bootstrap ...

  5. servlet实现文件上传,预览,下载和删除

    一.准备工作 1.1 文件上传插件:uploadify: 1.2 文件上传所需jar包:commons-fileupload-1.3.1.jar和commons-io-2.2.jar 1.3 将数据转 ...

  6. 上传图片,多图上传,预览功能,js原生无依赖

    最近很好奇前端的文件上传功能,因为公司要求做一个支持图片预览的图片上传插件,所以自己搜了很多相关的插件,虽然功能很多,但有些地方不能根据公司的想法去修改,而且需要依赖jQuery或Bootstrap库 ...

  7. javascript --- 文件上传即时预览 闭包实现多图片即时预览

    使用javascript原生功能实现,点击上传文件,然后再网页上显示出来 1. 初级显示 1.1 准备一个input标签和一个img标签 <input type=file id="fi ...

  8. 利用jquery.form.js实现Ajax无刷新图片上传及预览功能

    某些时候当我们做登记页面的时候可能需要上传图片,并实现即时预览的功能. 如果只是预览而不上传,可以使用ImagePreview来实现,方便简单.如果需要上传,那么你也可以使用uploadify无刷新上 ...

  9. kl-uploads 多文件上传与预览的实现

    功能描述 多文件的上传,图片添加预览功能,非图片只有名称列表 使用 <template><div class="demo"><klUploadhide ...

最新文章

  1. dubbo2.5.6从下载到编译成功并且部署成功过程
  2. Gazebo添加模型并控制模型运动作为动态障碍物(Ubuntu16.04, Gazebo7.16),附录动态链接库和静态链接库区别
  3. 计算机的主存储器可以分为哪两类,2017年计算机应用基础模拟试题「答案」(2)...
  4. CentOS下的Mysql的安装和使用
  5. Item Pipeline
  6. Java 实例 - 测试两个字符串区域是否相等
  7. 新浪微博最新的、通吃网络应用和Air应用的SDK问世了
  8. H5学习从0到1-H5的新特性(1)
  9. 2.微服务设计 --- 演化式架构师
  10. loadrunner中没有Mobile App协议,怎么录制App脚本
  11. Linux下PDF转图片格式
  12. [sig19]寒霜引擎中strand-based(基于线)的头发渲染
  13. ShowWindow函数用法。
  14. 【UI界面设计】网页设计基础笔记
  15. 基于A*搜索算法迷宫游戏开发
  16. 编程初学者快速上手实战套路
  17. c1科目三灯光全语言播报,驾照科目三灯光模拟考试语音提示
  18. 寒假每日一题——贝茜的报复
  19. 记录对接京东宙斯API -- 发布商品
  20. vue-tree-chart 组织架构-树形图-流程图(含鼠标右击事件)

热门文章

  1. 创建支持ssh的docker镜像
  2. 暗通道优先的图像去雾算法(下)
  3. 高性能IO -Reactor模式的实现
  4. Spring Security OAuth 个性化token
  5. Android -- TouchEvent的分发和截获方式
  6. button按钮无法提交表单问题发现与解决
  7. python操作mongo(2)
  8. C++和C#实现剪切板数据交互
  9. getInitParameter方法
  10. 以太网单播、组播、广播