用openoffice+jodconverter+webuploader+pdf.js实现文件上传、在线预览功能
一、背景
最近公司一个项目要实现一个文件上传以及多文档在线预览的功能,之前一直做无线工具开发的,没有涉及到这些东西。另外项目组缺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> <i class="fa fa-eye"></i> <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实现文件上传、在线预览功能相关推荐
- js html怎么加入图片,js实现图片上传并预览功能
思路:完成这个功能,首先需要美化上传图片的按钮,然后添加一个 标签,在图片上传之后,用新图片的src替换原来 标签中的src. 如下图所示,是原始的按钮样式: 美化步骤: (1)将上传图片标签采用绝对 ...
- php案例 文件上传并预览
作者:陈业贵 华为云享专家 51cto(专家博主 明日之星 TOP红人) 阿里云专家博主 文章目录 前言 代码 cyg.php 2.php 效果:也就是上传的文件里面的内容 前言 php案例 文件上传 ...
- uploadify java 下载_uploadify java实现多文件上传和预览
本文实例为大家分享了java文件上传和预览实现代码,供大家参考,具体内容如下 1.下载uploadify插件 2.index.html #uploader { position: relative; ...
- php 表格导入excel插件,BootStrap Fileinput插件和表格插件相结合实现导入Excel数据的文件上传、预览、提交的步骤...
这篇文章主要介绍了BootStrap Fileinput插件和Bootstrap table表格插件相结合实现文件上传.预览.提交的导入Excel数据操作步骤,需要的朋友可以参考下 bootstrap ...
- servlet实现文件上传,预览,下载和删除
一.准备工作 1.1 文件上传插件:uploadify: 1.2 文件上传所需jar包:commons-fileupload-1.3.1.jar和commons-io-2.2.jar 1.3 将数据转 ...
- 上传图片,多图上传,预览功能,js原生无依赖
最近很好奇前端的文件上传功能,因为公司要求做一个支持图片预览的图片上传插件,所以自己搜了很多相关的插件,虽然功能很多,但有些地方不能根据公司的想法去修改,而且需要依赖jQuery或Bootstrap库 ...
- javascript --- 文件上传即时预览 闭包实现多图片即时预览
使用javascript原生功能实现,点击上传文件,然后再网页上显示出来 1. 初级显示 1.1 准备一个input标签和一个img标签 <input type=file id="fi ...
- 利用jquery.form.js实现Ajax无刷新图片上传及预览功能
某些时候当我们做登记页面的时候可能需要上传图片,并实现即时预览的功能. 如果只是预览而不上传,可以使用ImagePreview来实现,方便简单.如果需要上传,那么你也可以使用uploadify无刷新上 ...
- kl-uploads 多文件上传与预览的实现
功能描述 多文件的上传,图片添加预览功能,非图片只有名称列表 使用 <template><div class="demo"><klUploadhide ...
最新文章
- dubbo2.5.6从下载到编译成功并且部署成功过程
- Gazebo添加模型并控制模型运动作为动态障碍物(Ubuntu16.04, Gazebo7.16),附录动态链接库和静态链接库区别
- 计算机的主存储器可以分为哪两类,2017年计算机应用基础模拟试题「答案」(2)...
- CentOS下的Mysql的安装和使用
- Item Pipeline
- Java 实例 - 测试两个字符串区域是否相等
- 新浪微博最新的、通吃网络应用和Air应用的SDK问世了
- H5学习从0到1-H5的新特性(1)
- 2.微服务设计 --- 演化式架构师
- loadrunner中没有Mobile App协议,怎么录制App脚本
- Linux下PDF转图片格式
- [sig19]寒霜引擎中strand-based(基于线)的头发渲染
- ShowWindow函数用法。
- 【UI界面设计】网页设计基础笔记
- 基于A*搜索算法迷宫游戏开发
- 编程初学者快速上手实战套路
- c1科目三灯光全语言播报,驾照科目三灯光模拟考试语音提示
- 寒假每日一题——贝茜的报复
- 记录对接京东宙斯API -- 发布商品
- vue-tree-chart 组织架构-树形图-流程图(含鼠标右击事件)