导读,此工具类中包含以下功能:
1、文件后缀判断
2、图片后缀判断
3、word后缀判断
4、Excel后缀判断
5、PDF后缀判断
6、使用pdfbox将整个pdf转换成图片
7、pdf2word
8、word2PDF
9、向PDF指定页插入图片
10、PDF指定位置覆盖
11、删除文件夹及以下文件(可能出现删不全的情况)
12、zip文件返回
13、打压缩包
代码:
package cn.org.enst.report.office.utils.processdocument;import cn.org.enst.common.exception.DbptException;
import cn.org.enst.common.utils.StringUtils;
import cn.org.enst.common.utils.file.FileUtils;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDPageTree;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.text.PDFTextStripper;import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;public class FileTypeUtils {/*** 文件后缀判断*/public static boolean verificationFile(String originFileName) {// 后缀String extName = originFileName.substring(originFileName.lastIndexOf(".") + 1);// 判断是不是图片、文档、excel、pdf、压缩包等文件后缀if (extName.matches("(tif|gif|png|jpg|jpeg|bmp|doc|docx|pdf|xls|xlsx|rar|zip)")) {return true;}// "文件格式错误"return false;}/*** 图片后缀判断*/public static boolean verificationImage(String originFileName) {// 后缀String extName = originFileName.substring(originFileName.lastIndexOf(".") + 1);// 判断是不是图片后缀if (extName.matches("(png|jpg|jpeg)")) {return true;}// "文件格式错误"return false;}/*** word后缀判断*/public static boolean verificationWord(String originFileName) {// 后缀String extName = originFileName.substring(originFileName.lastIndexOf(".") + 1);// 判断是不是图片后缀if (extName.matches("(doc|docx)")) {return true;}// "文件格式错误"return false;}/*** Excel后缀判断*/public static boolean verificationExcel(String originFileName) {// 后缀String extName = originFileName.substring(originFileName.lastIndexOf(".") + 1);// 判断是不是图片后缀if (extName.matches("(xls|xlsx)")) {return true;}// "文件格式错误"return false;}/*** PDF后缀判断*/public static boolean verificationPDF(String originFileName) {// 后缀String extName = originFileName.substring(originFileName.lastIndexOf(".") + 1);// 判断是不是图片后缀if (extName.matches("(pdf)")) {return true;}// "文件格式错误"return false;}/*** 使用pdfbox将整个pdf转换成图片** @param fileAddress 文件地址 如:C:\\Users\\user\\Desktop\\test* @param filename PDF文件名不带后缀名* @param type 图片类型 png 和jpg* @param pathList 图片输出位置*/public static void pdf2png(String fileAddress, String filename, String type, List<String> pathList) {
// long startTime = System.currentTimeMillis();// 将文件地址和文件名拼接成路径 注意:线上环境不能使用\\拼接File file = new File(fileAddress + "\\" + filename + ".pdf");try {// 写入文件PDDocument doc = PDDocument.load(file);PDFRenderer renderer = new PDFRenderer(doc);int pageCount = doc.getNumberOfPages();for (int i = 0; i < pageCount; i++) {// dpi为144,越高越清晰,转换越慢BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI// 将图片写出到该路径下pathList.add(fileAddress + "\\" + filename + "_" + (i + 1) + "." + type);ImageIO.write(image, type, new File(fileAddress + "\\" + filename + "_" + (i + 1) + "." + type));}long endTime = System.currentTimeMillis();
// System.out.println("共耗时:" + ((endTime - startTime) / 1000.0) + "秒"); //转化用时} catch (IOException e) {e.printStackTrace();}}/*** @param source 要转换的word文件* @param target 要转换成为的pdf文件*/public static void pdf2word(String source, String target) {try {//将pdf加载到对象中去PDDocument doc = PDDocument.load(new File(source));//得到pdf的页数int pagenumber = doc.getNumberOfPages();//设置转换后的名字
// pdfFile = pdfFile.substring(0, pdfFile.lastIndexOf("."));
// String fileName = pdfFile + ".doc";File file = new File(target);if (!file.exists()) {file.createNewFile();}FileOutputStream fos = new FileOutputStream(target);//设置输出字符集为UTF-8 因此该word应该使用UTF-8格式打开 如果你出现乱码那么你可以自己修改一下这里的格式Writer writer = new OutputStreamWriter(fos, "UTF-8");PDFTextStripper stripper = new PDFTextStripper();stripper.setSortByPosition(true);// 排序stripper.setStartPage(1);// 设置转换的开始页stripper.setEndPage(pagenumber);// 设置转换的结束页stripper.writeText(doc, writer);writer.close();doc.close();System.out.println("pdf转换word成功!");} catch (IOException e) {e.printStackTrace();}}/*** \** @param sourceUrl 要转换的word文件* @param targetUrl 要转换成为的pdf文件*/public static void word2PDF(String sourceUrl, String targetUrl) {int wdFormatPDF = 17;// PDF 格式ActiveXComponent app = null;Dispatch doc = null;try {app = new ActiveXComponent("Word.Application");app.setProperty("Visible", new Variant(false));Dispatch docs = app.getProperty("Documents").toDispatch();//转换前的文件路径String startFile = sourceUrl;//转换后的文件路劲String overFile = targetUrl;doc = Dispatch.call(docs, "Open", startFile).toDispatch();File tofile = new File(overFile);if (tofile.exists()) {tofile.delete();}Dispatch.call(doc, "SaveAs", overFile, wdFormatPDF);} catch (Exception e) {System.out.println(e.getMessage());} finally {Dispatch.call(doc, "Close", false);if (app != null)app.invoke("Quit", new Variant[]{});}//结束后关闭进程ComThread.Release();}/*** @param tempContentPathString pdf文件路径* @param tempSignPathList jpg图片路径集合* @param i 图片放在pdf第几页(下标从0开始)* @param pdfUrl pdf输出位置*/public static void PDFMergeJPGIndex(String tempContentPathString, List<String> tempSignPathList, int i, String pdfUrl) throws Exception {new File(pdfUrl.substring(0,pdfUrl.lastIndexOf(File.separator))).mkdirs();//"D:\\temp\\电力行标-报告.pdf"//打开PDF文件PDDocument doc = PDDocument.load(new FileInputStream(tempContentPathString));//获取所有页PDPageTree pages = doc.getDocumentCatalog().getPages();//获取第一页PDPage pdPage0 = pages.get(0);//获取第一页纸张信息PDRectangle mediaBox = pdPage0.getMediaBox();float lowerLeftX = mediaBox.getLowerLeftX();float lowerLeftY = mediaBox.getLowerLeftY();float width = mediaBox.getWidth();float height = mediaBox.getHeight();//有几张照片循环几次for (String s : tempSignPathList) {// 根据第一个纸张信息创建一张空白页PDPage pageOne = new PDPage(mediaBox);//获取照片PDImageXObject pdImage = PDImageXObject.createFromFile(s, doc);// 获取此页内容流PDPageContentStream contentStream = new PDPageContentStream(doc, pageOne, PDPageContentStream.AppendMode.APPEND, true);//照片写入contentStream.drawImage(pdImage, lowerLeftX, lowerLeftY, width, height);// 关闭内容流contentStream.close();pages.insertBefore(pageOne, pages.get(i + tempSignPathList.indexOf(s)));}doc.save(new File(pdfUrl));doc.close();}/*** pdf遮盖(不通用)* pdfUrl pdf路径* type 文档类型(区分不同文档类型,区分覆盖位置)*/public static void PDFFill(String pdfUrl, int type) throws Exception {//初始化数据float x = 0; // 替换为您需要遮盖的区域的X轴坐标float y = 0; // 替换为您需要遮盖的区域的Y轴坐标float w = 0; // 替换为遮盖区域的宽度float h = 0; // 替换为遮盖区域的高度//打开PDF文件PDDocument doc = PDDocument.load(new FileInputStream(pdfUrl));PDPageTree pages = doc.getDocumentCatalog().getPages();PDPage pdPage0 = pages.get(0);PDRectangle mediaBox = pdPage0.getMediaBox();// 创建内容流,将第一页的内容绘制到新页上(如果需要删除/遮盖某个区域,请在此内容流中进行相应操作)PDPageContentStream contentStream = new PDPageContentStream(doc, pdPage0, PDPageContentStream.AppendMode.APPEND, true);// 设置填充颜色(这里设置为白色,您可以根据需要更改颜色)contentStream.setNonStrokingColor(255, 255, 255); // 白色if (0 == type) {//方案、测评表x = 0f; // 替换为您需要遮盖的区域的X轴坐标y = 200f; // 替换为您需要遮盖的区域的Y轴坐标w = 500f; // 替换为遮盖区域的宽度h = 300f; // 替换为遮盖区域的高度}else if(1 == type){//调查表x = 0f; // 替换为您需要遮盖的区域的X轴坐标y = 145f; // 替换为您需要遮盖的区域的Y轴坐标w = 600f; // 替换为遮盖区域的宽度h = 150f; // 替换为遮盖区域的高度}// 绘制矩形遮盖指定区域contentStream.addRect(x, y, w, h);contentStream.fill();// 结束内容流contentStream.close();// 保存修改后的文档doc.save(pdfUrl);// 关闭文档doc.close();}/*** 删除文件夹及以下的文件*/public static void deleteFolder(File folder) {File[] files = folder.listFiles();if (files != null) {for (File file : files) {if (file.isDirectory()) {deleteFolder(file);} else {file.delete();}}}folder.delete();}/*** 文件返回*/public static void downloadZip(HttpServletRequest request, HttpServletResponse response, String zipPath) {//截取文件名String fileName = zipPath.substring(zipPath.lastIndexOf(File.separator) + 1);try {response.setCharacterEncoding("utf-8");// 导出使用"application/octet-stream"更标准response.setContentType("application/octet-stream");response.setHeader("Content-Disposition","attachment;filename=" + FileUtils.setFileDownloadHeader(request, fileName));FileUtils.writeBytes(zipPath, response.getOutputStream());} catch (IOException e) {e.printStackTrace();throw new DbptException(StringUtils.format("导出文件 ({}) !", fileName, e));}}/*** 打压缩包*/public static void compress(String fromPath, String toPath) throws Exception {File fromFile = new File(fromPath);File toFile = new File(toPath);if (!fromFile.exists()) {throw new DbptException(fromPath + "不存在!");}try (FileOutputStream outputStream = new FileOutputStream(toFile); CheckedOutputStream checkedOutputStream = new CheckedOutputStream(outputStream, new CRC32()); ZipOutputStream zipOutputStream = new ZipOutputStream(checkedOutputStream)) {//区分重载方法,无实际意义String baseDir = "";//进行一次循环为了去除最外层文件夹File[] files = fromFile.listFiles();for (File file : files) {compress(file, zipOutputStream, baseDir);}}}private static void compress(File file, ZipOutputStream zipOut, String baseDir) throws IOException {if (file.isDirectory()) {compressDirectory(file, zipOut, baseDir);} else {compressFile(file, zipOut, baseDir);}}private static void compressFile(File file, ZipOutputStream zipOut, String baseDir) throws IOException {if (!file.exists()) {return;}try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {ZipEntry entry = new ZipEntry(baseDir + file.getName());zipOut.putNextEntry(entry);int count;byte[] data = new byte[1024];while ((count = bis.read(data, 0, 1024)) != -1) {zipOut.write(data, 0, count);}}}private static void compressDirectory(File dir, ZipOutputStream zipOut, String baseDir) throws IOException {File[] files = dir.listFiles();if (files != null && ArrayUtils.isNotEmpty(files)) {for (File file : files) {compress(file, zipOut, baseDir + dir.getName() + File.separator);}}}
}