2021SC@SDUSC
在上篇博客中提到,如pdf、word一样的文件在系统中不仅可以转换成pdf的形式展示,也可以转换成图片的样式。在FileHandlerService中pdf2jpg实现了这个功能。
目录
office2pdf(inputFilePath,outputFilePath)
一、office文件转pdf功能实现:
office文件转换为pdf文件的浏览格式主要由类OfficeToPdfService实现。类里定义了一个final变量和officePluginManager,OfficePluginManager负责创建office文件转换器,在上面已经作了介绍。
private final static Logger logger = LoggerFactory.getLogger(OfficeToPdfService.class);
private final OfficePluginManager officePluginManager;
主要实现功能的方法是:
需要目标文件输入路径(inputFilePath)和转换后路径(outputFilePath)两个参数。
首先实例化一个officeDocumentConverter对象(由OfficePluginManager调用内部方法创建),判断目标文件路径是否为空(是否有文件存在):若为空,继续执行;若非空,方法结束。
若转换后的路径为空,通过目标文件路径获取转换后文件路径,之后再调用converterFile方法,创建文件目录;若转换后的路径非空,直接调用converterFile方法创建。
代码实现如下:
public void office2pdf(String inputFilePath, String outputFilePath) {
OfficeDocumentConverter converter = officePluginManager.getDocumentConverter();
if (null != inputFilePath) {
File inputFile = new File(inputFilePath);
// 判断目标文件路径是否为空
if (null == outputFilePath) {
// 转换后的文件路径
String outputFilePath_end = getOutputFilePath(inputFilePath);
if (inputFile.exists()) {
// 找不到源文件, 则返回
converterFile(inputFile, outputFilePath_end,converter);
}
} else {
if (inputFile.exists()) {
// 找不到源文件, 则返回
converterFile(inputFile, outputFilePath, converter);
}
}
}
}
public static void converterFile(File inputFile, String outputFilePath_end, OfficeDocumentConverter converter) {
File outputFile = new File(outputFilePath_end);
// 假如目标路径不存在,则新建该路径
if (!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs()) {
logger.error("创建目录【{}】失败,请检查目录权限!",outputFilePath_end);
}
converter.convert(inputFile, outputFile);
}
二、pdf转jpg
主要功能:pdf文件转换成jpg图片集
所需参数:pdfFilePath pdf文件路径;pdfName pdf文件名称;baseUrl 基础访问地址
返回结果:return 图片访问集合
该方法首先计算已将pdf转换成图片的图片本地相对路径;接着定义string类型变量imageFileSuffix作为之后使用的后缀,赋值".jpg";定义url前缀=基础访问地址+转码后的文件名字。
首先定义一个整数表示图片的数量,通过调用getConvertedPdfImage方法将pdf的本地路径转为图片的保存路径,之后再调用cacheservice.getPdfImageCache(key)。由于缓存cache的类型不同,getPdfImageCache(key)在接口cacheservice的子类中都有不同的实现。
一个是在cacheserviceredisimpl中:
public Integer getPdfImageCache(String key) {
RMapCache<String, Integer> convertedList = redissonClient.getMapCache(FILE_PREVIEW_PDF_IMGS_KEY);
return convertedList.get(key);
}
另一个是cacheserviceRockDBimpl中的:
@SuppressWarnings("unchecked")
public Integer getPdfImageCache(String key) {
Integer result = 0;
Map<String, Integer> map;
try{
map=(Map<String,Integer>)toObject(db.get(FILE_PREVIEW_PDF_IMGS_KEY.getBytes()));
result = map.get(key);
}catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
如果所有pdf文件都已经转成图片,在for循环里将前缀与后缀整合在一起作为图片访问集合返回。
public List<String> pdf2jpg(String pdfFilePath, String pdfName, String baseUrl) {
List<String> imageUrls = new ArrayList<>();
Integer imageCount = this.getConvertedPdfImage(pdfFilePath);
String imageFileSuffix = ".jpg";
String pdfFolder = pdfName.substring(0, pdfName.length() - 4);
String urlPrefix;
try {
urlPrefix = baseUrl + URLEncoder.encode(pdfFolder, uriEncoding).replaceAll("\\+", "%20");
} catch (UnsupportedEncodingException e) {
logger.error("UnsupportedEncodingException", e);
urlPrefix = baseUrl + pdfFolder;
}
// 前缀与后缀整合
if (imageCount != null && imageCount > 0) {
for (int i = 0; i < imageCount; i++) {
imageUrls.add(urlPrefix + "/" + i + imageFileSuffix);
}
return imageUrls;
}
这一部分是具体的功能实现代:创建PDDocument对象分析上传的pdf文件,统计pdf转换页数,创建文件转换目录,之后在for循环中按页完成图片转换。
图片文件路径imageFilePath=目录 + File.separator + pdf当前页码 + 后缀。
图片流BufferedImage调用pdfRenderer.renderImageWithDPI(pageIndex, 105, ImageType.RGB)方法生成图片。pdfRender来自一个可以对pdf提供操作的jar包,需要操作pdf的函数都可以通过它完成。
转换完成后,将该文件路径添加到已经成功转换jpg的队列中,返回图片地址。
try {
File pdfFile = new File(pdfFilePath);
PDDocument doc = PDDocument.load(pdfFile);
int pageCount = doc.getNumberOfPages();
PDFRenderer pdfRenderer = new PDFRenderer(doc);
int index = pdfFilePath.lastIndexOf(".");
String folder = pdfFilePath.substring(0, index);
File path = new File(folder);
if (!path.exists() && !path.mkdirs()) {
logger.error("创建转换文件【{}】目录失败,请检查目录权限!", folder);
}
String imageFilePath;
// 核心转换代码, 一页一页的转换
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
imageFilePath = folder + File.separator + pageIndex + imageFileSuffix;
// 定义图片相对路径
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 105, ImageType.RGB);
//调用pdfrender的方法实现转换
ImageIOUtil.writeImage(image, imageFilePath, 105);
//imageIO写入图片到相对路径下
imageUrls.add(urlPrefix + "/" + pageIndex + imageFileSuffix);
}
doc.close();
this.addConvertedPdfImage(pdfFilePath, pageCount);
} catch (IOException e) {
logger.error("Convert pdf to jpg exception, pdfFilePath:{}", pdfFilePath, e);
}
return imageUrls;
}
三、 office类型的其它文件转换成pdf
除pdf之外的office类型转换成pdf在OfficeToPdf中实现。处理文件之前首先创建一个文件转换器类变量,在较新的版本中叫OfficePluginManager,之前的版本中叫ConverterUtils。
public void office2pdf(String inputFilePath, String outputFilePath) {
OfficeDocumentConverter converter = converterUtils.getDocumentConverter();
if (null != inputFilePath) {
File inputFile = new File(inputFilePath);
// 判断目标文件路径是否为空
if (null == outputFilePath) {
// 转换后的文件路径
String outputFilePath_end = getOutputFilePath(inputFilePath);
if (inputFile.exists()) {
// 找不到源文件, 则返回
converterFile(inputFile, outputFilePath_end,converter);
}
} else {
if (inputFile.exists()) {
// 找不到源文件, 则返回
converterFile(inputFile, outputFilePath, converter);
}
}
}
}
首先根据文件输入路径定义存放转换后文件的路径,实现如下:将所有后缀用".pdf"替代。
public static String getOutputFilePath(String inputFilePath) {
return inputFilePath.replaceAll("."+ getPostfix(inputFilePath), ".pdf");
}
之后调用converterFile()方法完成转换,输出pdf文件。
public static void converterFile(File inputFile, String outputFilePath_end,
OfficeDocumentConverter converter) {
File outputFile = new File(outputFilePath_end);
// 假如目标路径不存在,则新建该路径
if (!outputFile.getParentFile().exists()) {
outputFile.getParentFile().mkdirs();
}
converter.convert(inputFile, outputFile);
}