This commit is contained in:
2025-10-24 10:20:31 +08:00
parent 4ba880ea40
commit 17bd458302
7 changed files with 850 additions and 587 deletions

View File

@@ -1,23 +1,30 @@
package com.point.strategy.common;
import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifDirectoryBase;
import com.itextpdf.text.*;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ResourceUtils;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageInputStream;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.*;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
@Slf4j
public class PdfFileHelper {
/*
水印间隔
@@ -117,7 +124,7 @@ public class PdfFileHelper {
for (int r = 0; r < grid_rows; r++) {
for (int j = 0; j < grid_cols; j++) {
//画网格矩形
content.setColorStroke(BaseColor.RED);
content.setColorStroke(BaseColor.BLACK);
float x = grid_left + grid_col_width * j;
float y = height - grid_top - grid_col_height * (r + 1);
content.rectangle(x, y, grid_col_width, grid_col_height);
@@ -133,7 +140,7 @@ public class PdfFileHelper {
//写入文本
content.beginText();
content.setColorFill(BaseColor.RED);
content.setColorFill(BaseColor.BLACK);
content.setFontAndSize(font, (int) Math.ceil(font_size * scale * 1.0));
content.setTextMatrix(0, 0);
//content.ShowTextAligned(Element.ALIGN_LEFT, textContent[r, j], text_left + grid_col_width*j +
@@ -238,6 +245,25 @@ public class PdfFileHelper {
}
}
/**
* 获取pdf文件总页数
* PdfReader
*
* @param f
* @return
*/
public static int getPdfPageCounOrOther(String f) {
try {
PdfReader pdfReader = new PdfReader(f);
PdfReader.unethicalreading = true;
int numberOfPages = pdfReader.getNumberOfPages();
pdfReader.close();
return numberOfPages;
} catch (Exception ex) {
return 1;
}
}
/**
* Pdf文件加水印文字--居中
*
@@ -350,41 +376,61 @@ public class PdfFileHelper {
* 合并Pdf
*
* @param fileArray pdf图片数组[]{"d:/a/1.pdf","d:/a/2.pdf"}
* @param tarFile 生成的目标pdf
* @return
*/
public static boolean mergePdf(String[] fileArray, String tarFile) {
//目标文件存在,则先删除
File _tarFile = new File(tarFile);
if (_tarFile.exists()) {
_tarFile.delete();
public static boolean mergePdf(String[] fileArray, String targetFile) {
if (fileArray == null || fileArray.length == 0) {
log.warn("输入的PDF文件数组为空无需合并。");
return true; // 或根据业务需求返回false
}
File target = new File(targetFile);
if (target.exists()) {
if (!target.delete()) {
log.error("无法删除已存在的目标文件: {}", targetFile);
return false;
}
}
Arrays.sort(fileArray);
Document document = null;
PdfCopy pdfCopy = null;
try {
Document doc = new Document();
PdfCopy pdf = new PdfCopy(doc, new FileOutputStream(tarFile));
doc.open();
for (int i = 0; i < fileArray.length; i++) {
if (fileArray[i] != null) {
PdfReader pdfReader = new PdfReader(fileArray[i]);
PdfReader.unethicalreading = true;
int numberOfPages = pdfReader.getNumberOfPages();
for (int page = 0; page < numberOfPages; page++) {
PdfImportedPage newPage = pdf.getImportedPage(pdfReader, page + 1);
pdf.addPage(newPage);
document = new Document();
pdfCopy = new PdfCopy(document, new FileOutputStream(targetFile));
document.open();
for (String filePath : fileArray) {
if (filePath == null || filePath.trim().isEmpty()) {
log.warn("发现一个空的PDF文件路径已跳过。");
continue;
}
PdfReader pdfReader = null;
try {
pdfReader = new PdfReader(filePath);
pdfCopy.addDocument(pdfReader);
} catch(Exception e) {
log.error("读取或合并文件 {} 时出错,已跳过此文件。", filePath, e);
} finally {
if (pdfReader != null) {
pdfReader.close();
}
pdf.freeReader(pdfReader);
pdfReader.close();
}
}
doc.close();
return true;
} catch (Exception ex) {
System.out.println("合并Pdf失败" + ex.getMessage());
} catch (IOException | DocumentException e) {
log.error("合并PDF过程中发生严重错误。", e);
return false;
} finally {
// 5. 在最外层的 finally 块中关闭 Document 和 PdfCopy
// Document.close() 会自动调用 PdfCopy.close() 和底层的流。
// 检查 document 是否为 null 并且已打开,以防在初始化时就发生异常。
if (document != null && document.isOpen()) {
document.close();
}
}
}
/*
* @Description 图片转pdf
* @Date 13:33 2019/6/10
@@ -398,6 +444,8 @@ public class PdfFileHelper {
Image png1 = Image.getInstance(source); //通过文件路径获取image
// float heigth = png1.getHeight();
// float width = png1.getWidth();
// 新增读取图片的EXIF方向信息
int orientation = getExifOrientation(source);
//new一个pdf文档
Document doc = new Document(null, 0, 0, 0, 0);
if (img == null) {
@@ -411,6 +459,8 @@ public class PdfFileHelper {
// int percent = getPercent2(heigth, width);
// png1.setAlignment(Image.MIDDLE);
// png1.scalePercent(percent+3);// 表示是原来图像的比例;
// 新增根据EXIF方向调整图片
adjustImageOrientation(png1, orientation);
doc.add(png1);
doc.close();
File mOutputPdfFile = new File(target); //输出流
@@ -426,6 +476,43 @@ public class PdfFileHelper {
}
// 新增获取图片的EXIF方向信息
private static int getExifOrientation(String imagePath) {
try {
File imageFile = new File(imagePath);
Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
// 遍历元数据目录,查找 EXIF 方向标签
for (Directory directory : metadata.getDirectories()) {
// 使用 ExifDirectoryBase 的常量
if (directory.containsTag(ExifDirectoryBase.TAG_ORIENTATION)) {
return directory.getInt(ExifDirectoryBase.TAG_ORIENTATION);
}
}
} catch (Exception e) {
System.err.println("读取EXIF方向失败: " + e.getMessage());
}
return 1; // 默认方向:正常
}
// 新增根据EXIF方向调整图片
private static void adjustImageOrientation(Image image, int orientation) throws DocumentException {
switch (orientation) {
case 1: // 正常
break;
case 3: // 旋转180度
image.setRotationDegrees(180);
break;
case 6: // 顺时针旋转90度
image.setRotationDegrees(90);
break;
case 8: // 逆时针旋转90度
image.setRotationDegrees(270);
break;
// 其他情况可以根据需要添加
}
}
/****
* 给PDF文件某些页增加马赛克
* @param srcFile 源文件
@@ -615,6 +702,23 @@ public class PdfFileHelper {
return outputStream;
}
public static int getTifPageCount(String filePath) {
int pageCount = 0;
try {
File file = new File(filePath);
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("TIFF");
ImageReader reader = readers.next();
reader.setInput(new FileImageInputStream(file));
pageCount = reader.getNumImages(true);
reader.dispose();
} catch (IOException e) {
e.printStackTrace();
}
return pageCount;
}
public static void main1(String[] args) {
String source = "C:\\Users\\MI\\Desktop\\13\\pdf\\b.pdf";
String target = "C:\\Users\\MI\\Desktop\\13\\pdf\\b-" + DateUtil.date2String(new Date(), 3) + ".pdf";
@@ -658,14 +762,12 @@ public class PdfFileHelper {
setWaterMark(srcFile, tarFile, markStr, fontSize, color, globalOblique);
}
public static void main5(String[] args) {
String tarFile = "C:\\Users\\MI\\Desktop\\13\\pdf\\mergePdf-" + DateUtil.date2String(new Date(), 3) + ".pdf";
String[] fileArray = {"C:\\Users\\MI\\Desktop\\13\\pdf\\k1.pdf", "C:\\Users\\MI\\Desktop\\13\\pdf\\k2.pdf"};
public static void main(String[] args) {
String tarFile = "/Users/ab/Desktop/pdf/test.pdf";
String[] fileArray = {"/Users/ab/Desktop/pdf/1.pdf", "/Users/ab/Desktop/pdf/2.pdf"};
mergePdf(fileArray, tarFile);
}
public static void main(String[] args) {
pageNo("C:\\Users\\MI\\Desktop\\13\\pdf\\caiwenhong.pdf","C:\\Users\\MI\\Desktop\\13\\pdf\\caiwenhong-pageNo.pdf");
}
}