目录
描述:
将本地pdf文件按找页码拆分为多个jpg文件,并保存到本地文件
测试代码:
@Test
public void testString() {
try {
byte[] pdfbytes = DownloadFileUtil.getBytes("D:\\jfapp\\file\\pdf\\temp.pdf");
DownloadFileUtil.getFile(pdfbytes, "D:\\jfapp\\file\\pdf\\", "tempppp.pdf");
DownloadFileUtil.pdfToImages("D:\\jfapp\\file\\pdf\\tempppp.pdf", "D:\\jfapp\\file\\pdf\\");
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
工具类:
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpStatus;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.jfsoft.interfaces.entity.AdiconResultImg;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 下载工具类
*
* @author JAVA
* @date 2020/12/18.
*/
@Slf4j
public class DownloadFileUtil {
// Base64 编码与解码
private static final java.util.Base64.Decoder DECODER_64 = java.util.Base64.getDecoder();
private static final java.util.Base64.Encoder ENCODER_64 = java.util.Base64.getEncoder();
/**
* 文件下载
*
* @param path 文件绝对路径
* @param fileName 文件名
* @return
* @throws Exception
*/
public static ResponseEntity download(String path, String fileName) {
try {
File file = new File(path);
if (!FileUtil.exist(path)) {
return ResponseEntity.status(HttpStatus.HTTP_NOT_FOUND).build();
}
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
headers.add("Last-Modified", new Date().toString());
headers.add("ETag", String.valueOf(System.currentTimeMillis()));
return ResponseEntity
.ok()
.headers(headers)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(new FileSystemResource(file));
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.HTTP_INTERNAL_ERROR).build();
}
}
/**
* 文件下载
*
* @param base64Str base64字符串
* @param fileName 文件名
* @return
* @throws Exception
*/
public static ResponseEntity downloadBase64(String base64Str, String fileName) {
ResponseEntity<InputStreamResource> body = null;
InputStream is = null;
try {
byte[] bytes = new Base64().decode(base64Str);
is = new ByteArrayInputStream(bytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
body = ResponseEntity
.ok()
.headers(headers)
.contentLength(is.available())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(new InputStreamResource(is));
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != is) {
is.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
return body;
}
public static void base64ContentToFile(String base64Content, String filePath) throws IOException {
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
// Base64解码到字符数组
byte[] bytes = DECODER_64.decode(base64Content);
ByteArrayInputStream byteInputStream = new ByteArrayInputStream(bytes);
bis = new BufferedInputStream(byteInputStream);
File file = new File(filePath);
File path = file.getParentFile();
if (!path.exists()) {
path.mkdirs();
}
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
// io
byte[] buffer = new byte[1024];
int length = bis.read(buffer);
while (length != -1) {
bos.write(buffer, 0, length);
length = bis.read(buffer);
}
// 刷新此输出流,强制写出所有缓冲的输出字节
bos.flush();
} catch (IOException e) {
e.getMessage();
} finally {
try {
bis.close();
fos.close();
bos.close();
} catch (IOException e) {
e.getMessage();
}
}
}
public static byte[] byte2Hex(byte[] bt) {
String jpg_base64 = null;
try {
PDDocument pdf = PDDocument.load(bt);
int size = pdf.getNumberOfPages();
//定义宽度
int width = 0;
//保存一张图片中的RGB数据
int[] singleImagRGB;
//定义高度,后买你用于叠加
int shiftHeight = 0;
//保存每张图片的像素值
BufferedImage imageResult = null;
//利用pdfBOX生成图像
PDDocument pdDocument = pdf;
PDFRenderer pdfRenderer = new PDFRenderer(pdDocument);
int pageLength = size;
//总计循环次数
int totalCount = pdDocument.getNumberOfPages() / pageLength + 1;
for (int m = 0; m < totalCount; m++) {
for (int x = 0; x < pageLength; x++) {
int pageIndex = x + (m * pageLength);
if (pageIndex == pdDocument.getNumberOfPages()) {
//System.out.println("循环次数 m = " + m);
break;
}
// dpi为图片的dpi,dpi越大,则图片越清晰,图片越大,转换耗费的时间也越多
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 86f, ImageType.RGB);
int imageHeight = image.getHeight();
int imageWidth = image.getWidth();
if (x == 0) {
//计算高度和偏移量
//使用第一张的宽度
width = imageWidth;
if ((pdDocument.getNumberOfPages() - m * pageLength) < pageLength) {
imageResult = new BufferedImage(width, imageHeight * (pdDocument.getNumberOfPages() - m * pageLength), BufferedImage.TYPE_INT_RGB);
} else {
imageResult = new BufferedImage(width, imageHeight * pageLength, BufferedImage.TYPE_INT_RGB);
}
} else {
// 将高度不断累加
shiftHeight += imageHeight;
}
singleImagRGB = image.getRGB(0, 0, width, imageHeight, null, 0, width);
imageResult.setRGB(0, shiftHeight, width, imageHeight, singleImagRGB, 0, width);
}
shiftHeight = 0;
}
pdDocument.close();
ByteArrayOutputStream baos;//io流
baos = new ByteArrayOutputStream();
ImageIO.write(imageResult, "jpg", baos);//写入流中
byte[] jpg_Bytes = baos.toByteArray();//转换成字节
// BASE64Encoder encoder = new BASE64Encoder();
// jpg_base64 = encoder.encodeBuffer(jpg_Bytes).trim();//转换成base64串
// jpg_base64 = jpg_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
// log.info("图片base64"+jpg_base64);
// baos.close();
// pdf.close();
// String photoShiLiu = toShiliu(jpg_base64);
// System.out.println(photoShiLiu);
return jpg_Bytes;
} catch (IOException exp) {
exp.printStackTrace();
System.out.println("转失败了!");
}
return null;
}
/**
* 获得指定文件的byte数组
**/
public static byte[] getBytes(String filePath) {
byte[] buffer = null;
try {
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
byte[] b = new byte[1000];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
bos.close();
buffer = bos.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return buffer;
}
/**
* 根据byte数组,生成文件
**/
public static void getFile(byte[] bfile, String filePath, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
try {
File dir = new File(filePath);
if (!dir.exists() && dir.isDirectory()) {//判断文件目录是否存在
dir.mkdirs();
}
file = new File(filePath + fileName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bfile);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
log.info("filePath >>>" + file.getPath());
}
/**
*
* @param pdfFilePath : pdf文件地址
* @param destDirFile : 最终jpg图片生成保存的目录
* @return java.util.List<com.jfsoft.interfaces.entity.AdiconResultImg>
* @描述: pdf 拆分转为jpg 图片 并返回
* @Date: 2023/6/12 11:49
**/
public static void pdfToImages( String pdfFilePath, String destDirFile) throws Exception {
final String destFormat = "jpg";//最终希望PDF文件转成的文件格式
final File file = new File(pdfFilePath);
PDDocument doc = null;
try {
doc = PDDocument.load(file);
PDFRenderer renderer = new PDFRenderer(doc);
int pages = doc.getNumberOfPages();//获取到当前PDF内的总页数
for (int i = 0; i < pages; i++) { //遍历每一页
//拼接生成的图片路径->D:/test/月份/月份(PDF后缀)-页数.jpg
int act = i + 1;//实际计数比计算机计数多一,因为计算机是从0计数
String destPath = destDirFile + file.getName() + "_" + act + "." + destFormat;
//BufferedImage image = renderer.renderImage(i);
BufferedImage image = renderer.renderImageWithDPI(i, 200f, ImageType.RGB);
File filepath = new File(destPath);
if (!filepath.exists()) {
filepath.mkdirs();//生成文件夹来存储输出的图片
}
File jpgFile = new File(destPath);//在此路劲内生成图片
ImageIO.write(image, destFormat, jpgFile);//传入参数,生成图片
}
} finally {
if (doc != null) {
doc.close();
}
}
}
/**
* @param path 源PDF路径
* @param fileName 源PDF文件名
* @param outputPath 拆分后输出的PDF路径
* @author Reverse_XML
* 把PDF 按页(逐页、单页)拆分(一页一页拆分,一页为一个新PDF文件)
*/
public static void splitPDFOneByOne(String path, String fileName, String outputPath) {
String sep = File.separator;
PdfReader reader = null;
int numberOfPages = 0;
try {
reader = new PdfReader(path + sep + fileName);
//reader = new PdfReader();
numberOfPages = reader.getNumberOfPages();
for (int i = 1; i <= numberOfPages; i++) {
Document document = null;
PdfCopy copy = null;
try {
document = new Document(reader.getPageSize(1));
String savePath = outputPath + sep +
fileName.substring(0, fileName.lastIndexOf(".")) + "_" + i + ".pdf";
copy = new PdfCopy(document, new FileOutputStream(savePath));
document.open();
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, i);
copy.addPage(page);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (document != null)
document.close();
if (copy != null)
copy.close();
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
if (reader != null)
reader.close();
}
}
}