IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> word、excel、ppt 办公文件 在线预览 -> 正文阅读

[系统运维]word、excel、ppt 办公文件 在线预览

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如果想要免费的,可以用 openoffice,实现原理就是:
通过第三方工具openoffice,将word、excel、ppt、txt等文件转换为pdf文件流;当然如果装了Adobe Reader XI,那把pdf直接拖到浏览器页面就可以直接打开预览,前提就是浏览器支持pdf文件浏览。

一、安装openoffice
1. windows环境

openoffice 安装windows 环境

2. linux环境

openoffice 安装 linux环境

二、springboot项目
2.1. 导入依赖
        <dependency>
            <groupId>com.artofsolving</groupId>
            <artifactId>jodconverter</artifactId>
            <version>2.2.1</version>
        </dependency>
2.2. controller
package com.gblfy.controller;

import com.gblfy.service.IPreviewService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

/**
 * @author gblfy
 * @date 2021-10-28
 */
@Api(tags = "在线预览入口")
@RestController
@RequestMapping("/file/onlinePreview")
public class PreviewController {

    @Autowired
    private IPreviewService previewService;//在线预览处理类

    /**
     * 在线预览主入口
     *
     * @param fileUrl
     * @param response
     * @throws Exception
     */
    @ApiOperation("在线预览主方法")
    @PostMapping("/api")
    public void onlinePreview(@RequestParam("fileUrl") String fileUrl, HttpServletResponse response) throws Exception {
        previewService.onlinePreview(fileUrl, response);
    }
}

2.2. 接口
package com.gblfy.service;

import javax.servlet.http.HttpServletResponse;

/**
 * 文件在线预览接口
 *
 * @author gblfy
 * @date 2021-10-28
 */
public interface IPreviewService {
    void onlinePreview(String url, HttpServletResponse response) throws Exception;
}

2.3. 实现类
package com.gblfy.service.impl;

import com.gblfy.consts.FileTypeConst;
import com.gblfy.service.IPreviewService;
import com.gblfy.utils.FileConvertUtil;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 在线预览处理类
 *
 * @author gblfy
 * @date 2021-10-28
 */
@Service
public class PreviewServiceImpl implements IPreviewService {

    /**
     * 文件在线预览
     *
     * @param fileUrl  预览的文件路径
     * @param response 以pdf文件流的形式返回浏览器完成预览操作
     * @throws Exception
     */
    @Override
    public void onlinePreview(String fileUrl, HttpServletResponse response) throws IOException {
        //对url中文件名称进行统一编码,解决400问题
        String uRLEncoder = FileConvertUtil.encodeUrlFileName(fileUrl);

        //获取文件类型 注意不要携带.
        String suffix = FileConvertUtil.suffixFromFileName(uRLEncoder);
        if (!FileTypeConst.TXT.equals(suffix) && !FileTypeConst.DOC.equals(suffix)
                && !FileTypeConst.DOCX.equals(suffix) && !FileTypeConst.XLS.equals(suffix)
                && !FileTypeConst.XLSX.equals(suffix) && !FileTypeConst.PPT.equals(suffix)
                && !FileTypeConst.PPTX.equals(suffix)) {
            throw new RuntimeException("该文件格式不支持预览");
        }

        //文件转换处理
        InputStream in = FileConvertUtil.convertNetFile(uRLEncoder, suffix);
        OutputStream outputStream = response.getOutputStream();

        //创建存放文件内容的数组
        byte[] buff = new byte[1024];
        //所读取的内容使用n来接收
        int n;
        //当没有读取完时,继续读取,循环
        while ((n = in.read(buff)) != -1) {
            //将字节数组的数据全部写入到输出流中
            outputStream.write(buff, 0, n);
        }
        //强制将缓存区的数据进行输出
        outputStream.flush();
        //关流
        outputStream.close();
        in.close();
    }
}

2.4. 格式转换

文件格式转换工具类

package com.gblfy.utils;

import com.artofsolving.jodconverter.DefaultDocumentFormatRegistry;
import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.DocumentFormat;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.StreamOpenOfficeDocumentConverter;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.*;

/**
 * 文件格式转换工具类
 *
 * @author gblfy
 * @date 2021-10-28
 */
@Component
public class FileConvertUtil {

    /**
     * 默认转换后文件后缀
     */
    private static final String DEFAULT_SUFFIX = "pdf";
    /**
     * openoffice_port
     */
    private static final Integer OPENOFFICE_PORT = 8100;

    /**
     * 方法描述 office文档转换为PDF(处理本地文件)
     *
     * @param sourcePath 源文件路径
     * @param suffix     源文件后缀
     * @return InputStream 转换后文件输入流
     * @author tarzan
     */
    public static InputStream convertLocaleFile(String sourcePath, String suffix) throws Exception {
        File inputFile = new File(sourcePath);
        InputStream inputStream = new FileInputStream(inputFile);
        return covertCommonByStream(inputStream, suffix);
    }

    /**
     * 方法描述  office文档转换为PDF(处理网络文件)
     *
     * @param netFileUrl 网络文件路径
     * @param suffix     文件后缀
     * @return InputStream 转换后文件输入流
     * @author tarzan
     */
    public static InputStream convertNetFile(String netFileUrl, String suffix) throws IOException {
        // 创建URL
        URL url = new URL(netFileUrl);
        // 试图连接并取得返回状态码
        URLConnection urlconn = url.openConnection();
        urlconn.connect();
        HttpURLConnection httpconn = (HttpURLConnection) urlconn;
        int httpResult = httpconn.getResponseCode();
        if (httpResult == HttpURLConnection.HTTP_OK) {
            InputStream inputStream = urlconn.getInputStream();

            //文件转换
            return covertCommonByStream(inputStream, suffix);
        }
        return null;
    }

    /**
     * 方法描述  将文件以流的形式转换
     *
     * @param inputStream 源文件输入流
     * @param suffix      源文件后缀
     * @return InputStream 转换后文件输入流
     * @author tarzan
     */
    public static InputStream covertCommonByStream(InputStream inputStream, String suffix) throws ConnectException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        OpenOfficeConnection connection = new SocketOpenOfficeConnection(OPENOFFICE_PORT);
        connection.connect();
        DocumentConverter converter = new StreamOpenOfficeDocumentConverter(connection);
        DefaultDocumentFormatRegistry formatReg = new DefaultDocumentFormatRegistry();
        DocumentFormat targetFormat = formatReg.getFormatByFileExtension(DEFAULT_SUFFIX);
        DocumentFormat sourceFormat = formatReg.getFormatByFileExtension(suffix);
        converter.convert(inputStream, sourceFormat, out, targetFormat);
        connection.disconnect();
        return outputStreamConvertInputStream(out);
    }

    /**
     * 方法描述 outputStream转inputStream
     *
     * @author tarzan
     */
    public static ByteArrayInputStream outputStreamConvertInputStream(final OutputStream out) {
        ByteArrayOutputStream baos = (ByteArrayOutputStream) out;
        return new ByteArrayInputStream(baos.toByteArray());
    }

    /**
     * 通过文件名获取文件后缀
     *
     * @param fileName 文件名称
     * @return 文件后缀
     */
    public static String suffixFromFileName(String fileName) {
        return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
    }

    /**
     * 对url中的文件名进行UTF-8编码
     *
     * @param url url
     * @return 文件名编码后的url
     */
    public static String encodeUrlFileName(String url) {
        String noQueryUrl = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length());
        int fileNameStartIndex = noQueryUrl.lastIndexOf('/') + 1;
        int fileNameEndIndex = noQueryUrl.lastIndexOf('.');
        String encodedFileName;
        try {
            encodedFileName = URLEncoder.encode(noQueryUrl.substring(fileNameStartIndex, fileNameEndIndex), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return null;
        }
        return url.substring(0, fileNameStartIndex) + encodedFileName + url.substring(fileNameEndIndex);
    }

    // public static void main(String[] args) {
    //     String url ="http://127.0.0.1:8080/flies/新建MicrosoftExcel工作表.xlsx";
    //     String ii = encodeUrlFileName(url);
    //     System.out.println(ii);
    // }
}

2.5. 配置类
package com.gblfy.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * web 配置类
 *
 * @author gblfy
 * @Date 2019/11/12日 下午5:03:32
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    /**
     * 在配置文件中配置的文件保存路径
     */
    @Value("${files.location}")
    private String files;

    /**
     * 静态资源映射
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        //本应用\static\editor\fonts
        registry.addResourceHandler("/flies/**").addResourceLocations("file:" + files);

    }
}

2.6. 扩展配置

说明:添加扩展配置原因
解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常

package com.artofsolving.jodconverter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @description: 重写 BasicDocumentFormatRegistry 文档格式
 * 
 * @Author: gblfy
 * @Data: 2021-10-27
 **/
public class BasicDocumentFormatRegistry implements DocumentFormatRegistry {

    private List/* <DocumentFormat> */ documentFormats = new ArrayList();

    public void addDocumentFormat(DocumentFormat documentFormat) {
        documentFormats.add(documentFormat);
    }

    protected List/* <DocumentFormat> */ getDocumentFormats() {
        return documentFormats;
    }

    /**
     * @param extension the file extension
     * @return the DocumentFormat for this extension, or null if the extension
     * is not mapped
     */
    @Override
    public DocumentFormat getFormatByFileExtension(String extension) {
        if (extension == null) {
            return null;
        }

        //将文件名后缀统一转化
        if (extension.indexOf("doc") >= 0) {
            extension = "doc";
        }
        if (extension.indexOf("ppt") >= 0) {
            extension = "ppt";
        }
        if (extension.indexOf("xls") >= 0) {
            extension = "xls";
        }
        String lowerExtension = extension.toLowerCase();
        for (Iterator it = documentFormats.iterator(); it.hasNext(); ) {
            DocumentFormat format = (DocumentFormat) it.next();
            if (format.getFileExtension().equals(lowerExtension)) {
                return format;
            }
        }
        return null;
    }

    @Override
    public DocumentFormat getFormatByMimeType(String mimeType) {
        for (Iterator it = documentFormats.iterator(); it.hasNext(); ) {
            DocumentFormat format = (DocumentFormat) it.next();
            if (format.getMimeType().equals(mimeType)) {
                return format;
            }
        }
        return null;
    }
}


2.7. 全局配置
  • windows环境
# linux
#files:
#  location: /app/files/
#  mapping: /flies/

# windows
files:
  location: D:/files/
  mapping: /flies/

#server:
#  port: 80
  • linux环境

```bash
# linux
files:
  location: /app/files/
  mapping: /flies/

# windows
#files:
#  location: D:/files/
#  mapping: /flies/

#server:
#  port: 80

安装字体
生成PDF乱码问题解决方案

2.8. 项目源码

https://gitee.com/gb_90/online-preview

2.9. 项目拉取
git clone git@gitee.com:gb_90/online-preview.git
2.10.效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、源码心得分享
3.1. 适配兼容

日常office 格式文件转换可以满足,支持文件格式很多,
例如:doc、docx、xls、xlsx、ppt、pptx、txt 等,这里不一一列举

3.2. 兼容不足
  • 效果图:
    虽然可以满足日常office文件转换场景,但是,实现效果和原版文件有差距,如果要求不要能接受就可以。

  • excel 转换有限制
    默认只支持a4纸大小,宽度超过,会在下一页打印,这一点不是太好。

  • 导致的原因
    转换内置了转换后的纸张大小

3.3. 解决方案

修改源码预览之前,对将要预览的尺寸大小,先办法获取到,然后再动态设置就好

格式测试链接
ppthttp://127.0.0.1:80/file/onlinePreview/api?fileUrl=http://127.0.0.1:80/flies/多彩工作总结计划PPT模板2.pptx
excelhttp://127.0.0.1:80/file/onlinePreview/apifileUrl=http://127.0.0.1:80/flies/中文测试.xlsx
wordhttp://127.0.0.1:80/file/onlinePreview/apifileUrl=http://127.0.0.1:80/flies/前端3天速成手册.docx
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-10-30 12:50:23  更:2021-10-30 12:52:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 22:45:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码