赞
踩
一、OpenOffice服务安装于Windows服务器上的情况;之后会写在Linux的centos7服务器上的情况下使用OpenOffice预览文件
1.了解如何实现如docx、doc、txt、ppt等office格式文件的预览 ?
(1):我们可以知道一般的浏览器都提供了可以直接查看pdf文件的功能,而对于txt、docx等office格式是不支持的,所以为了在不让用户下载文件的情况下快速查看
文件内容,文件的预览功能自然便是比较迫切的了,所以实现预览,无非便是将各类office格式的文件转换为如pdf格式等浏览器可以直接打开的格式文件,然后便可以使用合适的访问方式进行预览即可。
2.如何进行转换格式且预览?
(1):我所采用的是使用开源的软件OpenOffice进行转换,当然还有其他方式,不过目前我采用了这个方式。且看我的前一篇office格式转换为pdf格式文章的链接文章有介绍如何使用进行转换。当然这里我们需要预览的的是一个不确定的文件,并非一个直接固定的文件,所以这里我们还需要稍作修改代码。且看代码如下:
- /*
- * @param file_id :该变量为在数据库中保存文件信息的主键id,通过该id获取到
- * 关于文件在fastdfs中的GroupName以及RemoteFilePath等信息
- *
- */
- @RequestMapping("/previewfile")
- public ResponseEntity<byte[]> previewToPdf(int file_id) throws MyException, IOException {
- //1.通过该id获取到该文件信息
- EnclosureFile en = enclosureService.getById(file_id);
-
- //2.传递GroupName,及远程路径名RemoteFilePath通过FastDFS相关功能从服务器上下载到相关数据
- // 该数据为字节数组类型,若不知FastDFS且翻看我之前的文章即可
- byte[] buffFile = FastDFSUtil.download(en.getGroupName(),en.getRemoteFilePath());
-
- //3.现在已经得到需要预览的文件数据,当然我们是不知道其的文件格式的,所以我们可以做个判断
- // 若其为pdf或其他非office格式的文件则不转换,直接返回即可
- // 而文件格式,我们直接通过存在数据库中的信息获取即可
- // 其实文件格式也就是其后缀名,如txt,docx,xls等
- String fileType = en.getFileType();
-
- //4.这里做一个判断,其是否为office类型的格式,当然这里我就不写这一步了,我就为了方便就直接
- // 默认了格式符合要求,不过通过该文件类型便可以确定出文件名称
- // newFileName 为字节数组转换所成文件名称
- // pdfName 为后面转换成的pdf文件名称
-
- String newFileName = IdUtil.fastSimpleUUID()+"."+fileType;
- String pdfName = IdUtil.fastSimpleUUID()+".pdf";
- //5.现在就要翻开我之前写的那篇文章里面的转换方法了,可以发现OpenOffice提供的convert方法
- // 的两个参数都是File文件类型,而现在我们得到的是数据为字节数组byte[]
- // 故而,我们便可以直接将byte[]类型转换为File类型不就ok了
- // 下方的语句,中使用到了byteToFile函数,这个函数我就放在后面了,这里就叙述一下其中
- // 函数的参数:1.buffFile为上方得到的字节数组,2.D:"\\OpenOffice"+File.separator :为
- // 字节数组转换成文件后的文件夹目录,3.newFileName 为转换后的文件名称
- File sourceFile =
- OpenOfficeUtil.byteToFile(buffFile,"D:\\OpenOffice"+File.separator,newFileName);
-
- //6.现在已经得到了从字节数组转换而来的文件 sourceFile
- // 可以着手开始转换成pdf了,看到下方是否眼熟
- // 现在已经得到了convert函数的最重要的两个参数,输入文件与最终的pdf文件
- File inputfile = new File("D:\\OpenOffice\\"+newFileName);
- File outputfile = new File("D:\\OpenOffice\\"+pdfName);
-
- //7.建立OpenOffice连接,确保OpenOffice服务已经打开
- OpenOfficeConnection connection = new SocketOpenOfficeConnection("127.0.0.1",8100);
- try {
- connection.connect();
- DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
- converter.convert(inputfile,outputfile);
- connection.disconnect();
- inputfile.delete(); //转换成功记得将之前的文件删除,先保留pdf文件即可
-
- //8.到这里文件已经转换成功,且成功得到了pdf文件,即outputfile
- // 而现在得到了pdf文件,但是要如何从vue中进行访问到pdf呢
- // 果断出手,将得到的pdf文件果断进行转换成字节数组byte[]进行返回给前端进行访问即可
- // 可以看到,下方又出现了一个新方法,为fileToByteArray该函数即为将文件转为字节数组的方法
- byte[] pdfByte = OpenOfficeUtil.fileToByteArray(outputfile);
-
- outputfile.delete(); //既然已经得到了字节数组数据,记得将产生的pdf文件进行删除
-
- //9.现在pdf格式的字节数组已经果断拿到,那么接下来便是将其返回给前端,可以看到该Controller
- // 方法的返回值格式为 : ResponseEntity<byte[]>
- // 这个格式大有可为,直接在前端采用 blob格式便可以果断访问,后面会给出vue的相关代码
- // 所以现在果断出手,设置ResponseEntity返回的一些必要准备,如HttpHeaders的设置
- // 下方有些HttpHeader不用设置,不过为了保险起见,我便都设置了,其中的
- // attachment是设置让浏览器下载的,当然我们是预览,所以不用下载,但是这里设置了
- // 也ok,只要前端改一下,不下载就行,但是也不保证有需求,想下载转换了的pdf文件,所以我
- // 暂且保留了
- HttpHeaders headers = new HttpHeaders();
- headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
- headers.setContentLength(outputfile.length());
- String fileName = URLEncoder.encode(outputfile.getName(),"utf-8");
- headers.setContentDispositionFormData("attachment",fileName);
-
- //10.这里便是将相关参数传递到该ResponseEntity中
- ResponseEntity<byte[]> responseEntity =
- new ResponseEntity<byte[]>(pdfByte,headers,HttpStatus.OK);
-
- return responseEntity; //直接返回即可,若前端配置的有拦截状态码记得使用status===200
-
- }catch (ConnectException e) {
- e.printStackTrace();
- }
-
- return null; //这里就返回个null即可
-
-
- }
3.其中用到的两个文件格式转换函数如下:
- // 1. 字节数组转换为文件
- /*
- * 将byte[] 转为 File 文件
- * @param: bfile 文件的byte数组 byte[]
- * @param: filepath 要写入的文件位置 "D:\\OpenOffice" + File.separator
- * @param: filename 写入之后的文件名称如 "xxx.docx"
- *
- */
-
- public static File byteToFile(byte[] bfile,String filePath,String fileName)
- {
- BufferedOutputStream bos = null;
- FileOutputStream fos = null;
- File file = null;
-
- try {
- File dir = new File(filePath); //创建了一个文件目录,若不存在则建立该目录
- if(!dir.exists()&&dir.isDirectory()){//判断文件目录是否存在
- dir.mkdirs();
- }
- file = new File(filePath+"\\"+fileName); //创建一个文件,
- fos = new FileOutputStream(file); //将
- bos = new BufferedOutputStream(fos);
- bos.write(bfile); //将字节写入文件中
-
- return file;
-
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (bos != null) {
- try {
- bos.close();
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- }
- if (fos != null) {
- try {
- fos.close();
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- }
- }
-
- return null;
- }
-
-
- // 2. 文件如pdf转换为字节数组
- /*
- * 将文件转为字节数组
- * file change to byte[]
- */
- public static byte[] fileToByteArray(File file) throws IOException {
- byte[] fileByte = new byte[(int)file.length()];
- // FileInputStream是InputStream的子类,用于从文件中读取信息
- FileInputStream fis = new FileInputStream(file);
-
- // 利用ByteArrayOutputStream将FileInputStream文件数据读出来
- // ByteArrayOutputStream用来在内存中创建缓冲区,所有送往"流"的数据都要放置在此缓冲区
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] b = new byte[1024];
- int len;
- while((len = fis.read(b)) != -1 ) {
- // write(byte[], int off, int len): 写入字节数组b,从b的第off下标开始,写入len个字节
- bos.write(b, 0, len);
- }
-
- // toByteArray()方法得到文件的字节数组
- fileByte = bos.toByteArray();
- return fileByte;
- }
4.前端vue的相关代码实现:
- //预览页面,预览txt,pdf,doc,xls,ppt
- // editPage包含了文件id的信息
- // 发送axios请求
- filePreview(editPage){
-
- this.$axios({
- method:'GET',
- url:this.dbURL+'/document/previewfile?file_id='+editPage.id,
- headers:{"Authorization":localStorage.getItem("token")},
- responseType: 'arraybuffer'
- //responseType: 'blob'
- }).then(res=>{
- console.log("excute previewFile ...")
- console.log(res)
- console.log(res.data)
-
- let a = document.createElement('a');
- let blob = new Blob([res.data],{
- type:'application/pdf' //也是必不可少的
- });
- let objectUrl = window.URL.createObjectURL(blob);
- window.open(objectUrl) //这一步应该就是其中精髓了
-
- })
-
-
- },
到此便实现了简洁明了的文件预览功能,主要是要理解其中该功能实现流程便可以一步步将其实现出来,上面代码只是基于windows服务器的简单预览版本。
**********************************************************分割线**********************************************
二、linux系统centos7中使用OpenOffice的预览版本
其实也就是将文件路径稍微设置一下,使用如下代码:将路径分别进行设置一下即可,这样当项目部署于Linux系统上时则同样稳定运行
- //filePath是自己规定的,也就是后面pdf文件产生时放在的文件夹路径
- //不过这个路径一旦确定,便不应随便更改,且用于删除文件时候
- //该文件夹路径也必须保持一致
-
- String filePath = " ";
- String osName = System.getProperty("os.name");
- if(Pattern.matches("Linux.*",osName))
- { System.out.println("当前处于Linux系统.");
- filePath = "/usr/local/TempOpenOffice";
- }
- else if(Pattern.matches("Windows.*", osName)) {
- System.out.println("当前处于Windows系统.");
- filePath = "D:\\OpenOfficeTemp";
- }
-
- File dir = new File(filePath);
- // 判断文件目录是否存在,若不存在则建立OpenOffice文件夹,且是文件夹
- if(!dir.exists()){
- dir.mkdirs();
- //创建了相关文件夹,但若是当前如D盘不存在则换为C盘,linux则不会出现该情况
- }
-
- //4.建立好一个输出pdf文件,之后通过OutputStream向该文件写入数据
- //File.separatorChar 在windows 为 \\ 在linxu系统为 /
- File outputfile = new File(filePath+File.separatorChar+newFilePdfName);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。