PDF、PPT、PPTX转图片

日期:2018-02-08       浏览:861

一 PDF转图片

1.1 maven 配置

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox-app</artifactId>
    <version>2.0.2</version>
</dependency>

1.2 具体代码

package com.qbian.util;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * Created by Qbian on 2018/2/7.
 * 将 PDF 文件转 图片
 */
public class PdfBoxUtils {

    private static final Logger LOG = LoggerFactory.getLogger(PdfBoxUtils.class);

    private static final String PIC_TYPE = "PNG";

    private PdfBoxUtils() {}

    /**
     * 将本地 pdf 文件转图片,测试文件 http://vodtv.butel.com/e27a9d11462a4529a3fd2072e85e0138.pdf
     * @param localFilePath 本地 pdf 文件地址
     * @param localImageDir 项目相对路径保存文件夹
     * @param localDirPath 本地绝对路径保存文件夹
     * @return 可访问的地址 数组
     * @throws IOException 转化异常
     */
    public static String[] pdf2Pic(String localFilePath
                                    , String localImageDir
                                    , String localDirPath) throws IOException {

        LOG.info("localFilePath={}, localDirPath={}", localFilePath, localDirPath);

        File file = new File(localFilePath);
        String fileName = file.getName();

        PDDocument doc = PDDocument.load(file);
        PDFRenderer renderer = new PDFRenderer(doc);

        int pageCount = doc.getNumberOfPages();

        String[] arr = new String[pageCount];

        for(int i = 0; i < pageCount; i ++) {
            // 方式一:第二个参数设置缩放比(即像素)
            BufferedImage image = renderer.renderImageWithDPI(i, 296);

            // 方式二:第二个参数设置缩放比(即像素)
//            BufferedImage image1 = renderer.renderImage(i, 2.5f);
            arr[i] = localImageDir + fileName +  "_" + (i + 1) + "." + PIC_TYPE;

            String absolutePath = localDirPath + fileName +  "_" + (i + 1) + "." + PIC_TYPE;
            File pngFile = new File(absolutePath);

            // 判断本地文件是否存在
            if(pngFile.exists()) {
                continue;
            }

            ImageIO.write(image, PIC_TYPE, pngFile);
        }

        doc.close();

        return arr;
    }

}

二 PPT、PPTX转图片

2.1 maven 配置

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.15</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>3.15</version>
</dependency>

2.2 具体代码

package com.qbian.util;

import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;

import org.apache.poi.hslf.usermodel.*;
import org.apache.poi.xslf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by Qbian on 2018/2/8.
 * 将 PPT、PPTX 文件转 图片
 */
public class PoiUtils {

    private static final Logger LOG = LoggerFactory.getLogger(PoiUtils.class);

    private static final String PIC_TYPE  = "PNG";

    private PoiUtils() {}

    /**
     * 将 pptx 文件转 图片,测试文件 http://vodtv.butel.com/d77fc0151d5a46ea9952f320f95fcc39.pptx
     * @param localFilePath pptx 本地文件地址
     * @param fileName 文件名
     * @param localImageDir 项目相对路径保存文件夹
     * @param localDirPath 本地绝对路径保存文件夹
     * @return 可访问的地址 数组
     * @throws IOException
     */
    public static String[] pptx2Pic(String localFilePath
                                    , String fileName
                                    , String localImageDir
                                    , String localDirPath) throws IOException {

        LOG.info("localFilePath={},fileName={},localImageDir={},localDirPath={}", localFilePath, fileName, localImageDir, localDirPath);

        FileInputStream is = new FileInputStream(localFilePath);
        XMLSlideShow ppt = new XMLSlideShow(is);

        is.close();

        Dimension pgSize = ppt.getPageSize();
        java.util.List<XSLFSlide> slides = ppt.getSlides();
        String[] arr = new String[ppt.getSlides().size()];

        for (int i = 0; i < slides.size(); i ++ ) {
            // 防止中文乱码
            for(XSLFShape shadow : slides.get(i).getShapes() ) {
                if(shadow instanceof XSLFTextShape) {
                    XSLFTextShape tsh = (XSLFTextShape) shadow;
                    for (XSLFTextParagraph p : tsh) {
                        for (XSLFTextRun r : p) {
                            r.setFontFamily("宋体");
                        }
                    }
                }
            }

            BufferedImage image = new BufferedImage(pgSize.width, pgSize.height, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics = image.createGraphics();

            graphics.setPaint(Color.white);
            graphics.fill(new Rectangle2D.Float(0, 0, pgSize.width, pgSize.height));

            slides.get(i).draw(graphics);

            String absolutePath = localDirPath + fileName + "_" + (i + 1) + "." + PIC_TYPE;

            arr[i] = localImageDir + fileName + "_" + (i + 1) + "." + PIC_TYPE;

            File pngFile = new File(absolutePath);

            // 判断本地文件是否存在
            if(pngFile.exists()) {
                continue;
            }

            FileOutputStream outputStream = new FileOutputStream(absolutePath);
            ImageIO.write(image, PIC_TYPE, outputStream);

            outputStream.close();
        }

        return arr;
    }

    /**
     * 将 ppt 文件转 图片,测试文件 http://vodtv.butel.com/e24c6573a57249348abb323fe3bf1c82.ppt
     * @param localFilePath pptx 本地文件地址
     * @param fileName 文件名
     * @param localImageDir 项目相对路径保存文件夹
     * @param localDirPath 本地绝对路径保存文件夹
     * @return 可访问的地址 数组
     * @throws IOException
     */
    public static String[] ppt2Pic(String localFilePath
                                    , String fileName
                                    , String localImageDir
                                    , String localDirPath) throws IOException {

        LOG.info("localFilePath={},fileName={},localImageDir={},localDirPath={}", localFilePath, fileName, localImageDir, localDirPath);

        FileInputStream is = new FileInputStream(localFilePath);
        HSLFSlideShow ppt = new HSLFSlideShow(is);

        is.close();

        Dimension pgSize = ppt.getPageSize();
        List<HSLFSlide> slides = ppt.getSlides();
        String[] arr = new String[slides.size()];

        for (int i = 0; i < slides.size(); i ++) {
            // 防止中文乱码
            for (HSLFShape shape : slides.get(i).getShapes()) {
                if(shape instanceof HSLFShape) {
                    HSLFTextShape tsh = (HSLFTextShape) shape;
                    for (HSLFTextParagraph p : tsh) {
                        for (HSLFTextRun r : p) {
                            r.setFontFamily("宋体");
                        }
                    }
                }
            }

            BufferedImage image = new BufferedImage(pgSize.width, pgSize.height, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics = image.createGraphics();

            graphics.setPaint(Color.white);
            graphics.fill(new Rectangle2D.Float(0, 0, pgSize.width, pgSize.height));

            slides.get(i).draw(graphics);

            String absolutePath = localDirPath + fileName + "_" + (i + 1) + "." + PIC_TYPE;

            arr[i] = localImageDir + fileName + "_" + (i + 1) + "." + PIC_TYPE;

            File pngFile = new File(absolutePath);

            // 判断本地文件是否存在
            if(pngFile.exists()) {
                continue;
            }

            FileOutputStream outputStream = new FileOutputStream(absolutePath);
            ImageIO.write(image, PIC_TYPE, outputStream);
            outputStream.close();
        }

        return arr;
    }
}

三 其它配置

使用的 spring boot 开发,所以这里就只给出 controller 和其它工具类的具体实现。

3.1 controller 具体代码

package com.qbian.web;

import com.qbian.enums.MessageEnum;
import com.qbian.response.Response;
import com.qbian.util.FileUtils;
import com.qbian.util.PdfBoxUtils;
import com.qbian.util.PoiUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;

/**
 * Created by Qbian on 2018/2/7.
 */
@RestController
public class IndexContrl {

    private static final Logger LOG = LoggerFactory.getLogger(IndexContrl.class);

    @Value("${resources.image-local-dir}")
    private String localImageDir;

    // 缓存 本地文件夹目录
    private String localDirPath = "";

    @GetMapping("/file2pic")
    public Response<String[]> index( HttpServletRequest request) {

        if("".equals(localDirPath)) {
            try {
                // 获取项目资源路径
                File file = ResourceUtils.getFile("classpath:static/files/test_e27a9d11462a4529a3fd2072e85e0138.pdf");
                localDirPath = file.getParent() + "/";
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                LOG.error("获取项目资源路径出错,e.message={}", e.getMessage());
                return new Response(MessageEnum.SYSTEM_ERROR, null);
            }
        }

        String docUrl = request.getParameter("url");
        File sf = new File(docUrl);
        String fileName = sf.getName();

        // 取得文件的后缀名
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase();

        if(!"PDF".equals(ext) && !"PPTX".equals(ext) && !"PPT".equals(ext)) {
            LOG.error("不支持的文件类型 ext={}", ext);
            return new Response(MessageEnum.FILE_TYPE_ERROR, null);
        }

        String localFilePath = localDirPath + fileName;

        LOG.info("docUrl={},ctxPath={}", docUrl, localFilePath);

        // 下载文件到本地
        if(!FileUtils.downloadFile(docUrl, localFilePath)) {
            return new Response(MessageEnum.DOWNLOAD_ERROR, null);
        }

        try {
            String[] arr = null;
            
            if("PDF".equals(ext)) { // PDF
                arr = PdfBoxUtils.pdf2Pic(localFilePath, localImageDir, localDirPath);
            } else if("PPTX".equals(ext)) { // PPTX
                arr = PoiUtils.pptx2Pic(localFilePath, fileName, localImageDir, localDirPath);
            } else { // PPT
                arr = PoiUtils.ppt2Pic(localFilePath, fileName, localImageDir, localDirPath);
            }

            return new Response(MessageEnum.SUCCESS, arr);
        } catch (IOException e) {
            e.printStackTrace();
            LOG.error("文件转 图片出错,e.message={}", e.getMessage());
            return new Response(MessageEnum.CONVERT_ERROR, null);
        }
    }

}
上面还导入了配置文件(application.properties)的配置信息,配置文件内容如下:
# 下载的文件和转换后的图片保存到 resources/static/files 文件夹下
resources.image-local-dir=/files/

3.2 下载网络文件工具类(FileUtils)

package com.qbian.util;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;

/**
 * Created by Qbian on 2018/2/7.
 * 下载 网络文件 到本地
 */
public class FileUtils {

    private FileUtils() {}

    /**
     * 下载文件到本地
     * @param remotePath 网络文件地址
     * @param localFilePath 本地文件地址
     * @return 是否成功
     */
    public static Boolean downloadFile(String remotePath, String localFilePath) {

        OutputStream os = null;
        InputStream is = null;

        try {
            URL url = new URL(remotePath);
            URLConnection urlConnection = url.openConnection();
            urlConnection.setConnectTimeout(15 * 1000);
            is = urlConnection.getInputStream();
            byte[] bs = new byte[1024];
            int len;
            File sf = new File(localFilePath);

            // 判断本地文件是否存在
            if (sf.exists()) {
                return true;
            }

            // 判断本地文件路径是否存在
            if(!sf.getParentFile().exists()) {
                sf.getParentFile().mkdirs();
            }

            os = new FileOutputStream(localFilePath);
            while ((len = is.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
        } catch (Exception e) {
            return false;
        } finally {
            try {
                if(os != null) {
                    os.close();
                }
                if(is != null) {
                    is.close();
                }
            } catch (IOException e) {
                return false;
            }
        }

        return true;
    }
}

3.3 返回数据格式定义(Response)

package com.qbian.response;

import com.qbian.enums.MessageEnum;

/**
 * Created by Qbian on 2018/2/7.
 */
public class Response<T> {
    public int code;
    public String message;
    public T data;

    public Response(MessageEnum messageEnum, T data) {
        this.code = messageEnum.getCode();
        this.message = messageEnum.getMessage();
        this.data = data;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

3.4 返回消息及其状态码

package com.qbian.enums;

/**
 * 返回码及其描述信息
 * Created by Qbian on 2018/2/7.
 */
public enum MessageEnum {
    SUCCESS(0, "成功"),
    SYSTEM_ERROR(-999, "系统异常"),
    DOWNLOAD_ERROR(-998, "下载文件出错"),
    CONVERT_ERROR(-997, "转换文档失败"),
    FILE_TYPE_ERROR(-996, "不支持的文件类型")
    ;

    private Integer code;
    private String message;

    MessageEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
扫码关注有惊喜

(转载本站文章请注明作者和出处 qbian)

暂无评论

Copyright 2016 qbian. All Rights Reserved.

文章目录