2021SC@SDUSC
项目中处理各类文件时都会声明一个FileUtils变量,FileUtils类提供了很多类处理文件时都需要进行的一些准备工作,这些基本操作会重复出现在很多,比如统计文件集合、获取路径、分析文件类型、统一编码格式等,为了避免出现过多重复代码而造成空间浪费,把这些代码都封装起来放在FileUtils类中实现,需要调用时直接声明对象即可。
这样操作还有一个好处就是项目需要更新时,直接在FileUtils类中更改代码即可,方便且效率更高。FileUtils提供的功能可大致分为:
1、统计集合:
统计已经转换过的文件集合(缓存);
public Map<String, String> listConvertedFiles() {
return cacheService.getPDFCache();
}
2、获取路径
在处理pdf文件转换成图片之前根据pdf的本地路径获取转换成图片后的本地相对路径;
public Integer getConvertedPdfImage(String key) {
return cacheService.getPdfImageCache(key);
}
3、获取文件类型
这个方法中为了保障数据安全性,防止参数中存在“.”符号或其他特殊字符,先抽取出文件名,再获取文件类型。文件类型包括图片(jpg、png等)、压缩包(zip、rar等)、office类型(ppt、word等)、simtext、多媒体(MP4等)、cad文件。
public FileType typeFromUrl(String url) {
String nonPramStr = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length());
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
return typeFromFileName(fileName);
//先获取文件名字排除不良因素影响
}
private FileType typeFromFileName(String fileName) {
String[] simText = ConfigConstants.getSimText();
String[] media = ConfigConstants.getMedia();
// 获取所有系统可以处理的文件
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
//filename中符合“.”最后出现的位置之后的字符串就是文件类型
if (listPictureTypes().contains(fileType.toLowerCase())) {
return FileType.picture;
}
if (listArchiveTypes().contains(fileType.toLowerCase())) {
return FileType.compress;
}
if (listOfficeTypes().contains(fileType.toLowerCase())) {
return FileType.office;
}
if (Arrays.asList(simText).contains(fileType.toLowerCase())) {
return FileType.simText;
}
if (Arrays.asList(media).contains(fileType.toLowerCase())) {
return FileType.media;
}
if ("pdf".equalsIgnoreCase(fileType)) {
return FileType.pdf;
}
if ("dwg".equalsIgnoreCase(fileType)) {
return FileType.cad;
}
return FileType.other;
}
值得一提的是,这里把pdf从office文件中单独拎出来。这是由于系统中很多文件最后都会以pdf的形式展示,所以这个方法会被多个类重复写,因此有必要单拎出来完成。 同样的还有添加转换成pdf后的文件缓存这个方法。
0
public void addConvertedFile(String fileName, String value){
cacheService.putPDFCache(fileName, value);
}
获取图片类型集合:
public List<String> listPictureTypes(){
List<String> list = Lists.newArrayList();
list.add("jpg");
list.add("jpeg");
list.add("png");
list.add("gif");
list.add("bmp");
list.add("ico");
list.add("RAW");
return list;
}
获取压缩包类型文件的集合:
public List<String> listArchiveTypes(){
List<String> list = Lists.newArrayList();
list.add("rar");
list.add("zip");
list.add("jar");
list.add("7-zip");
list.add("tar");
list.add("gzip");
list.add("7z");
return list;
}
获取office文件集合:
public List<String> listOfficeTypes() {
List<String> list = Lists.newArrayList();
list.add("docx");
list.add("doc");
list.add("xls");
list.add("xlsx");
list.add("ppt");
list.add("pptx");
return list;
}
获取文件的相对路径
从绝对路径中截取。fileDir的定义如下:
FILE_DIR = OfficeUtils.getHomePath() + File.separator + "file" + File.separator;
/**
* @param absolutePath 绝对路径
* @return 相对路径
*/
public String getRelativePath(String absolutePath) {
return absolutePath.substring(fileDir.length());
}
PdfUtils类
该类中的pdf2jpg()方法实现了pdf->jpg的转换 优化、分片、异步。
1、初始化
List<String> imageUrls = new ArrayList<>();
Integer imageCount = fileUtils.getConvertedPdfImage(pdfFilePath);
String imageFileSuffix = ".jpg";
String pdfFolder = pdfName.substring(0, pdfName.length() - 4);
String urlPrefix = null;
try {
urlPrefix = baseUrl + URLEncoder.encode(URLEncoder.encode(pdfFolder, uriEncoding).replaceAll("\\+", "%20"), uriEncoding);
} 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;
}
其中imageUrls为图片地址List
imageCount为图片总数
imageFileSuffix为图片后缀
pdfFolder为图片存储的目录
urlPrefix为图片前缀地址。
如果imageCount>0的话,说明这个文件已经转换过,直接返回图片路径List
2、核心方法:pdf->的转换
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();
}
String imageFilePath;
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
imageFilePath = folder + File.separator + pageIndex + imageFileSuffix;
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 105, ImageType.RGB);
ImageIOUtil.writeImage(image, imageFilePath, 105);
imageUrls.add(urlPrefix + "/" + pageIndex + imageFileSuffix);
}
doc.close();
fileUtils.addConvertedPdfImage(pdfFilePath, pageCount);
} catch (IOException e) {
logger.error("Convert pdf to jpg exception, pdfFilePath:{}", pdfFilePath, e);
}
PDDocument.load(pdfFile)为读取pdf文件 doc.getNumberOfPages()为总页数
然后调用PDF渲染类,创建图片存储的目录。
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
imageFilePath = folder + File.separator + pageIndex + imageFileSuffix;
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 105, ImageType.RGB);
ImageIOUtil.writeImage(image, imageFilePath, 105);
imageUrls.add(urlPrefix + "/" + pageIndex + imageFileSuffix);
}
fileUtils.addConvertedPdfImage(pdfFilePath, pageCount);
} catch (IOException e) {
logger.error("Convert pdf to jpg exception, pdfFilePath:{}", pdfFilePath, e);
}