手机端APP需要展示pdf文件内容,如果直接用APP打开pdf,将会是一个很大的烦扰,需要解决安卓和苹果同时兼容,这样实现务必会耗费比较多的时间,其实可以采取曲线救国的策略,服务器把pdf进行处理,其中一种就是将pdf转成图片,这样APP基本无需处理。

后端采用的java,把pdf转换图片后,有几页pdf文件就会生成几个图片,如果只需要一个图片,进行合并即可。

调错过程

刚开始的时候本地测试没有问题,但是上了服务器,发现有部分转图片后格式不正确,看日志发现有个提示

No glyph for 47286 (CID 06b1) in font SimSun

刚开始默认认为是字体库缺少,然后从windows上这个目录C:WindowsFonts,找到了字体库进行了Linux服务器的字体更新,但经过测试发现并没有什么作用



字体更新方法:

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

尝试是否是jar包问题

后来尝试考虑引入字体库jar包试试,引入了com.itextpdf的itext-asian和itextpdf,经过测试果然没有问题了

下面是所有代码,pdf转图片,图片合并,如果有需要可以图片压缩

引入包:pdfbox需要2.0以上,以下不支持转图片

org.apache.pdfbox pdfbox 2.0.4 org.apache.pdfbox fontbox 2.0.4 com.itextpdf itext-asian 5.2.0 compile com.itextpdf itextpdf 5.5.9 compile

pdf转图片

* PDF文件转PNG/JPEG图片

* @param PdfFilePathpdf完整路径

* @param imgFilePath图片存放的文件夹

* @param dpi越大转换后越清晰,相对转换速度越慢,一般电脑默认96dpi

import com.lowagie.text.pdf.PdfReader; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.PDFRenderer; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; public static String pdf2ImageDemo(String PdfFilePath, String dstImgFolder, int dpi) { String outMixPicUrl=""; String outMixPicUrl=""; File file = new File(PdfFilePath); PDDocument pdDocument; try { String imgPDFPath = file.getParent(); int dot = file.getName().lastIndexOf('.'); // 获取图片文件名 String imagePDFName = file.getName().substring(0, dot); String imgFolderPath = null; if (dstImgFolder.equals("")) { // 获取图片存放的文件夹路径 imgFolderPath = imgPDFPath + File.separator + imagePDFName; } else { imgFolderPath = dstImgFolder; } if (createDirectory(imgFolderPath)) { pdDocument = PDDocument.load(file); PDFRenderer renderer = new PDFRenderer(pdDocument); PdfReader reader = new PdfReader(PdfFilePath); int pages = reader.getNumberOfPages();// 获取PDF页数 System.out.println("PDF page number is:" + pages); StringBuffer imgFilePath = null; List inputFileNameList=new ArrayList(); for (int i = 0; i < pages; i++) { String imgFilePathPrefix = imgFolderPath + File.separator + imagePDFName; imgFilePath = new StringBuffer(); imgFilePath.append(imgFilePathPrefix); imgFilePath.append("_"); imgFilePath.append(String.valueOf(i + 1)); imgFilePath.append(".png");// PNG File dstFile = new File(imgFilePath.toString()); BufferedImage image = renderer.renderImageWithDPI(i, dpi); ImageIO.write(image, "png", dstFile);// PNG inputFileNameList.add(imgFilePath.toString()); } pdDocument.close(); //图片合并 outMixPicUrl=imgFolderPath + File.separator + imagePDFName+".png"; append(inputFileNameList,outMixPicUrl,false); System.out.println("PDF文档转PNG图片成功!"); } else { System.out.println("PDF文档转PNG图片失败:" + "创建" + imgFolderPath + "失败"); } } catch (IOException e) { e.printStackTrace(); } return outMixPicUrl; } private static boolean createDirectory(String folder) { File dir = new File(folder); if (dir.exists()) { return true; } else { return dir.mkdirs(); } }

图片合并

public static void append(List inputFileNameList, String outputFileName, boolean isX) { System.out.println(inputFileNameList.get(0)); System.out.println(outputFileName); if (inputFileNameList == null || inputFileNameList.size() == 0) { return; } try { boolean isFirstPng = true; BufferedImage outputImg = null; int outputImgW = 0; int outputImgH = 0; for (String pngFileName : inputFileNameList) { if (isFirstPng) { isFirstPng = false; outputImg = ImageIO.read(new File(pngFileName)); outputImgW = outputImg.getWidth(); outputImgH = outputImg.getHeight(); } else { BufferedImage appendImg = ImageIO.read(new File(pngFileName)); int appendImgW = appendImg.getWidth(); int appendImgH = appendImg.getHeight(); if (isX) { outputImgW = outputImgW + appendImgW; outputImgH = outputImgH > appendImgH ? outputImgH : appendImgH; } else { outputImgW = outputImgW > appendImgW ? outputImgW : appendImgW; outputImgH = outputImgH + appendImgH; } // create basic image Graphics2D g2d = outputImg.createGraphics(); BufferedImage imageNew = g2d.getDeviceConfiguration().createCompatibleImage(outputImgW, outputImgH, Transparency.TRANSLUCENT); g2d.dispose(); g2d = imageNew.createGraphics(); int oldImgW = outputImg.getWidth(); int oldImgH = outputImg.getHeight(); g2d.drawImage(outputImg, 0, 0, oldImgW, oldImgH, null); if (isX) { g2d.drawImage(appendImg, oldImgW, 0, appendImgW, appendImgH, null); } else { g2d.drawImage(appendImg, 0, oldImgH, appendImgW, appendImgH, null); } g2d.dispose(); outputImg = imageNew; } } writeImageLocal(outputFileName, outputImg); } catch (Exception e) { e.printStackTrace(); } } private static void writeImageLocal(String fileName, BufferedImage image) { if (fileName != null && image != null) { try { File file = new File(fileName); ImageIO.write(image, "png", file); } catch (IOException e) { e.printStackTrace(); } } }