使用pdfBox实现pdf转图片,解决中文方块乱码等问题

目录

1.引入依赖

2.pdf转图片工具类

3.出现的问题

4.问题解决


1.引入依赖


    org.apache.pdfbox
    pdfbox
    2.0.13

2.pdf转图片工具类

package com.yzy.service.common.util;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
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;

/**
 * 类功能描述:
 *
 * @author:xxx
 * @createTime:2019/1/4 9:00
 */
public class PdfToImage {

    private static final Logger logger = LoggerFactory.getLogger(PdfToImage.class);

    //经过测试,dpi为96,100,105,120,150,200中,105显示效果较为清晰,体积稳定,dpi越高图片体积越大,一般电脑显示分辨率为96
    public static final float DEFAULT_DPI = 105;
    //默认转换的图片格式为jpg
    public static final String DEFAULT_FORMAT = "jpg";

    /**
     * pdf转图片
     *
     * @param pdfPath PDF路径
     * @return 图片路径
     */
    public static void pdfToImage(String pdfPath, String imgPath) {
        try {
                       
           System.setProperty("sun.java2d.cmm","sun.java2d.cmm.kcms.KcmsServiceProvider");
            //图像合并使用参数
            // 总宽度
            int width = 0;
            // 保存一张图片中的RGB数据
            int[] singleImgRGB;
            int shiftHeight = 0;
            //保存每张图片的像素值
            BufferedImage imageResult = null;
            //利用PdfBox生成图像
            PDDocument pdDocument = PDDocument.load(new File(pdfPath));
            PDFRenderer renderer = new PDFRenderer(pdDocument);
            //循环每个页码
            for (int i = 0, len = pdDocument.getNumberOfPages(); i < len; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, DEFAULT_DPI, ImageType.RGB);
                int imageHeight = image.getHeight();
                int imageWidth = image.getWidth();
                //计算高度和偏移量
                if (i == 0) {
                    //使用第一张图片宽度;
                    width = imageWidth;
                    //保存每页图片的像素值
                    imageResult = new BufferedImage(width, imageHeight * len, BufferedImage.TYPE_INT_RGB);
                } else {
                    // 计算偏移高度
                    shiftHeight += imageHeight;
                }
                singleImgRGB = image.getRGB(0, 0, width, imageHeight, null, 0, width);
                // 写入流中
                imageResult.setRGB(0, shiftHeight, width, imageHeight, singleImgRGB, 0, width);
            }
            pdDocument.close();
            // 写图片
            ImageIO.write(imageResult, DEFAULT_FORMAT, new File(imgPath));
        } catch (Exception e) {
            logger.error("PDF转图片失败");
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
  pdfToImage("C://Users//LFG//Desktop//temp_1546570068959.pdf","C://Users//LFG//Desktop//temp_1546570068959.jpg");
    }

}

3.出现的问题

一些简单的pdf文件转换没有什么问题,但是一些比较复杂的,例如用了少见的字体样式就会出现问题。

出现的问题,例如中文变成方块□,0里有点等等

4.问题解决

(1)运行通用方法注意查看日志,如果打印出类似这样的日志(例:Using fallback AdobeSongStd-Light for CID-keyed font STSong-Light),就说明系统没有安装STSong-Light字体,pdfbox使用AdobeSongStd-Light字体来替代了。如果出现方块,就说明没有这种字体,并且替代字体也没有,日志也有相应的其他提示。

(2)windows安装字体

       缺少什么字体去搜索引擎搜索下载对应字体,然后再windows里直接安装ttf/otf等格式结尾的文件即可,或者在系统目录下C:\Windows\Fonts,只需把字体文件拖进来便会提示安装

(3)linux下安装字体

通常linux缺少的常用字体,在windows目录下C:\Windows\Fonts都能找到对应的字体文件,拷贝到linux上即可,没有的字体去搜索下载都能找到

#cd /usr/share/fonts/   // 进入系统自带的字体目录
#mkdir myfonts  // myfonts 是你自己随便取得文件夹名字
#将字体文件拷贝到这个文件夹下,在cd /usr/share/fonts/目录下执行以下命令
#mkfontscale   
#mkfontdir
#fc-cache -fv           //更新字体缓存
#source /etc/profile    // 执行以下命令让字体生效
#fc-list    // 查看系统中所有得字体,可用于测试是否安装字体成功

 

你可能感兴趣的:(java,工具类)