手机端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();
}
}
}