|
@@ -0,0 +1,178 @@
|
|
|
+package org.springblade.manager.utils;
|
|
|
+import org.apache.pdfbox.pdmodel.PDDocument;
|
|
|
+import org.apache.pdfbox.pdmodel.PDPage;
|
|
|
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
|
|
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
|
|
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
|
|
+import org.apache.pdfbox.text.PDFTextStripper;
|
|
|
+import org.apache.pdfbox.text.TextPosition;
|
|
|
+import org.springblade.common.utils.CommonUtil;
|
|
|
+import org.springblade.manager.service.impl.AlbumServiceImpl;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+/**
|
|
|
+ * 识别pdf 照片号和底片号
|
|
|
+ * @author LHB
|
|
|
+ */
|
|
|
+public class PhotoAndNegativeNumberFiller {
|
|
|
+ // 内部类用于存储标记位置信息
|
|
|
+ private static class MarkerPosition {
|
|
|
+ int pageIndex;
|
|
|
+ float x;
|
|
|
+ float y;
|
|
|
+ float width;
|
|
|
+ float height;
|
|
|
+ boolean isPhotoMarker; // true表示照片号,false表示底片号
|
|
|
+
|
|
|
+ MarkerPosition(int pageIndex, float x, float y, float width, float height, boolean isPhotoMarker) {
|
|
|
+ this.pageIndex = pageIndex;
|
|
|
+ this.x = x;
|
|
|
+ this.y = y;
|
|
|
+ this.width = width;
|
|
|
+ this.height = height;
|
|
|
+ this.isPhotoMarker = isPhotoMarker;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param inputPath 旧pdf地址
|
|
|
+ * @param outputPath 新pdf地址
|
|
|
+ * @param initialValue 开始值
|
|
|
+ * @param endValue 结束值
|
|
|
+ * @param negativeNumber 底片号
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public static int fillNumbers(String inputPath, String outputPath,
|
|
|
+ int initialValue, Integer endValue,
|
|
|
+ String negativeNumber) throws IOException {
|
|
|
+
|
|
|
+ List<MarkerPosition> markers = new ArrayList<>();
|
|
|
+ int currentPhotoNumber = initialValue;
|
|
|
+
|
|
|
+ try (PDDocument document = PDDocument.load(CommonUtil.getOSSInputStream(inputPath))) {
|
|
|
+ // 第一步:查找所有【照片号:】和【底片号:】标记的位置
|
|
|
+ PDFTextStripper stripper = new PDFTextStripper() {
|
|
|
+ private int currentPage = 0;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void startPage(PDPage page) throws IOException {
|
|
|
+ super.startPage(page);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void writeString(String string, List<TextPosition> textPositions) throws IOException {
|
|
|
+ /// 检查是否包含目标文本
|
|
|
+ if (string.contains("照片号:")) {
|
|
|
+ // 找到目标文本的位置
|
|
|
+ for (TextPosition text : textPositions) {
|
|
|
+ String unicode = text.getUnicode();
|
|
|
+ if (unicode.contains(":")) {
|
|
|
+ // 记录冒号后的位置
|
|
|
+ float x = text.getXDirAdj() + text.getWidthDirAdj();
|
|
|
+ float y = text.getYDirAdj();
|
|
|
+ float width = text.getWidthDirAdj();
|
|
|
+ float height = text.getHeightDir();
|
|
|
+
|
|
|
+ markers.add(new MarkerPosition(
|
|
|
+ currentPage,
|
|
|
+ x, y, width, height, true
|
|
|
+ ));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 检查是否包含目标文本
|
|
|
+ if (string.contains("底片号:")) {
|
|
|
+ // 找到目标文本的位置
|
|
|
+ for (TextPosition text : textPositions) {
|
|
|
+ String unicode = text.getUnicode();
|
|
|
+ if (unicode.contains(":")) {
|
|
|
+ // 记录冒号后的位置
|
|
|
+ float x = text.getXDirAdj() + text.getWidthDirAdj();
|
|
|
+ float y = text.getYDirAdj();
|
|
|
+ float width = text.getWidthDirAdj();
|
|
|
+ float height = text.getHeightDir();
|
|
|
+
|
|
|
+ markers.add(new MarkerPosition(
|
|
|
+ currentPage,
|
|
|
+ x, y, width, height, false
|
|
|
+ ));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void endPage(PDPage page) throws IOException {
|
|
|
+ super.endPage(page);
|
|
|
+ currentPage++;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理所有页面以查找标记
|
|
|
+ stripper.getText(document);
|
|
|
+
|
|
|
+ // 第二步:在标记位置填充号码
|
|
|
+ for (int i = 0; i < document.getNumberOfPages(); i++) {
|
|
|
+ PDPage page = document.getPage(i);
|
|
|
+ PDRectangle pageSize = page.getMediaBox();
|
|
|
+
|
|
|
+ // 收集当前页的所有标记
|
|
|
+ List<MarkerPosition> pageMarkers = new ArrayList<>();
|
|
|
+ for (MarkerPosition marker : markers) {
|
|
|
+ if (marker.pageIndex == i) {
|
|
|
+ pageMarkers.add(marker);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!pageMarkers.isEmpty()) {
|
|
|
+ try (PDPageContentStream contentStream = new PDPageContentStream(
|
|
|
+ document, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
|
|
|
+
|
|
|
+ contentStream.setFont(PDType1Font.HELVETICA, 10);
|
|
|
+ contentStream.setNonStrokingColor(0, 0, 0); // 黑色
|
|
|
+
|
|
|
+ // 计算并绘制号码
|
|
|
+ for (MarkerPosition marker : pageMarkers) {
|
|
|
+
|
|
|
+ if (endValue != null && currentPhotoNumber > endValue) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 调整坐标系统
|
|
|
+ float x = marker.x + 2;
|
|
|
+ float y = pageSize.getHeight() - marker.y - marker.height + 4;
|
|
|
+
|
|
|
+ contentStream.beginText();
|
|
|
+ contentStream.newLineAtOffset(x, y);
|
|
|
+
|
|
|
+ if (marker.isPhotoMarker) {
|
|
|
+ // 处理照片号
|
|
|
+ if (endValue != null && currentPhotoNumber > endValue) {
|
|
|
+ continue; // 跳过超过结束值的照片号
|
|
|
+ }
|
|
|
+
|
|
|
+ contentStream.showText(String.valueOf(currentPhotoNumber));
|
|
|
+ currentPhotoNumber++;
|
|
|
+ } else {
|
|
|
+ // 处理底片号
|
|
|
+ contentStream.showText(negativeNumber);
|
|
|
+ }
|
|
|
+
|
|
|
+ contentStream.endText();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存文档
|
|
|
+ document.save(outputPath);
|
|
|
+ }
|
|
|
+
|
|
|
+ return currentPhotoNumber - 1;
|
|
|
+ }
|
|
|
+}
|