|
@@ -0,0 +1,386 @@
|
|
|
|
+package org.springblade.meter.utils;
|
|
|
|
+
|
|
|
|
+import com.itextpdf.text.BaseColor;
|
|
|
|
+import com.itextpdf.text.Element;
|
|
|
|
+import com.itextpdf.text.Image;
|
|
|
|
+import com.itextpdf.text.Rectangle;
|
|
|
|
+import com.itextpdf.text.pdf.*;
|
|
|
|
+import com.itextpdf.text.pdf.parser.*;
|
|
|
|
+import org.springblade.common.constant.CommonConstant;
|
|
|
|
+import org.springblade.core.tool.utils.Func;
|
|
|
|
+import org.springblade.manager.entity.TextdictInfo;
|
|
|
|
+import org.springblade.manager.vo.PDFIndexInfo;
|
|
|
|
+import org.springblade.system.cache.ParamCache;
|
|
|
|
+
|
|
|
|
+import java.io.*;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+
|
|
|
|
+public class PdfAddimgUtil {
|
|
|
|
+
|
|
|
|
+ public static void pdfAddImgInfo(String pdfUrl, String keyword, Map<Long, TextdictInfo> textMap) throws Exception {
|
|
|
|
+ String file_path = FileUtils.getSysLocalFileUrl();
|
|
|
|
+ String signImg = file_path+"/print/241dc221f83929a87d55ce700d6a4cd7.png";
|
|
|
|
+
|
|
|
|
+ File pdfFile = new File(pdfUrl);
|
|
|
|
+ byte[] pdfData = new byte[(int) pdfFile.length()];
|
|
|
|
+ FileInputStream inputStream = null;
|
|
|
|
+ try {
|
|
|
|
+ inputStream = new FileInputStream(pdfFile);
|
|
|
|
+ inputStream.read(pdfData);
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw e;
|
|
|
|
+ } finally {
|
|
|
|
+ if (inputStream != null) {
|
|
|
|
+ try {
|
|
|
|
+ inputStream.close();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ inputStream.close();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ List<PDFIndexInfo> positions = findKeywordPostions(pdfData, keyword);
|
|
|
|
+
|
|
|
|
+ System.out.println("total:" + positions.size());
|
|
|
|
+ if (positions != null && positions.size() > 0) {
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < positions.size(); i++) {
|
|
|
|
+
|
|
|
|
+ PDFIndexInfo pdfIndexInfo = positions.get(i);
|
|
|
|
+ float[] position = pdfIndexInfo.getDataInfo();
|
|
|
|
+ TextdictInfo textdictInfo = textMap.get(Func.toLong(pdfIndexInfo.getPkeyid()));
|
|
|
|
+ float pyzbx = 0;
|
|
|
|
+ float pyzby = 0;
|
|
|
|
+ String type ="2";
|
|
|
|
+ if(textdictInfo!=null){
|
|
|
|
+ pyzbx = Func.toFloat(textdictInfo.getPyzbx());
|
|
|
|
+ pyzby = Func.toFloat(textdictInfo.getPyzby());
|
|
|
|
+ type = textdictInfo.getType()+"";
|
|
|
|
+ }
|
|
|
|
+ gaizhang(pdfFile, new File(pdfUrl), (int) position[0], position[1], position[2], signImg,pyzbx,pyzby,type);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static void gaizhang(File src, File dest, int page, float x, float y, String imagePath,float pyzbx,float pyzby,String type) throws Exception {
|
|
|
|
+ // 读取模板文件
|
|
|
|
+ InputStream input = new FileInputStream(src);
|
|
|
|
+ PdfReader reader = new PdfReader(input);
|
|
|
|
+ PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
|
|
|
|
+ Rectangle pageSize = reader.getPageSize(1);
|
|
|
|
+ float height = pageSize.getHeight();
|
|
|
|
+ float width = pageSize.getWidth();
|
|
|
|
+ if(type.equals("6")){
|
|
|
|
+ x = width * x - 27+pyzbx;
|
|
|
|
+ y = height - height * y - 30+pyzby;
|
|
|
|
+ imagePath = "/Users/hongchuangyanfa/Desktop/print/ht1234567890.png";
|
|
|
|
+ }else{
|
|
|
|
+ x = width * x - 20+pyzbx;
|
|
|
|
+ y = height - height * y - 8+pyzby;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 读图片
|
|
|
|
+ Image image = Image.getInstance(imagePath);
|
|
|
|
+
|
|
|
|
+ // 获取操作的页面
|
|
|
|
+ PdfContentByte under = stamper.getOverContent(page);
|
|
|
|
+ // 添加图片
|
|
|
|
+
|
|
|
|
+ // 设置图片的新宽度和高度
|
|
|
|
+ float newWidth = 75f; // 新的宽度
|
|
|
|
+ float newHeight = image.getScaledHeight() * (newWidth / image.getScaledWidth()); // 根据宽度计算高度
|
|
|
|
+ image.scaleAbsolute(newWidth, newHeight); // 设置图片的新尺寸
|
|
|
|
+ //调整图片尺寸
|
|
|
|
+ image.setAbsolutePosition(x, y);
|
|
|
|
+ under.addImage(image);
|
|
|
|
+ // 假设的under.addImage方法,需要传入图片路径和大小参数
|
|
|
|
+ stamper.close();
|
|
|
|
+ reader.close();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 【功能描述:添加图片和文字水印】 【功能详细描述:功能详细描述】
|
|
|
|
+ *
|
|
|
|
+ * @param srcFile 待加水印文件
|
|
|
|
+ * @param destFile 加水印后存放地址
|
|
|
|
+ * @param text 加水印的文本内容
|
|
|
|
+ * @param textWidth 文字横坐标
|
|
|
|
+ * @param textHeight 文字纵坐标
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ public void addWaterMark(String srcFile, String destFile, String text,
|
|
|
|
+ int textWidth, int textHeight) throws Exception {
|
|
|
|
+ // 待加水印的文件
|
|
|
|
+ PdfReader reader = new PdfReader(srcFile);
|
|
|
|
+ // 加完水印的文件
|
|
|
|
+ PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(
|
|
|
|
+ destFile));
|
|
|
|
+ int total = reader.getNumberOfPages() + 1;
|
|
|
|
+ PdfContentByte content;
|
|
|
|
+ // 设置字体
|
|
|
|
+ BaseFont font = BaseFont.createFont();
|
|
|
|
+ // 循环对每页插入水印
|
|
|
|
+ for (int i = 1; i < total; i++) {
|
|
|
|
+ // 水印的起始
|
|
|
|
+ content = stamper.getUnderContent(i);
|
|
|
|
+ // 开始
|
|
|
|
+ content.beginText();
|
|
|
|
+ // 设置颜色 默认为蓝色
|
|
|
|
+ content.setColorFill(BaseColor.BLUE);
|
|
|
|
+ // content.setColorFill(Color.GRAY);
|
|
|
|
+ // 设置字体及字号
|
|
|
|
+ content.setFontAndSize(font, 38);
|
|
|
|
+ // 设置起始位置
|
|
|
|
+ // content.setTextMatrix(400, 880);
|
|
|
|
+ content.setTextMatrix(textWidth, textHeight);
|
|
|
|
+ // 开始写入水印
|
|
|
|
+ content.showTextAligned(Element.ALIGN_LEFT, text, textWidth,
|
|
|
|
+ textHeight, 45);
|
|
|
|
+ content.endText();
|
|
|
|
+ }
|
|
|
|
+ stamper.close();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * findKeywordPostions
|
|
|
|
+ *
|
|
|
|
+ * @param pdfData
|
|
|
|
+ * @param keyword
|
|
|
|
+ * @return List<float [ ]> : float[0]:pageNum float[1]:x float[2]:y
|
|
|
|
+ * @throws IOException
|
|
|
|
+ */
|
|
|
|
+ public static List<PDFIndexInfo> findKeywordPostions(byte[] pdfData,
|
|
|
|
+ String keyword) throws IOException {
|
|
|
|
+ List<PDFIndexInfo> result = new ArrayList<PDFIndexInfo>();
|
|
|
|
+ List<PdfPageContentPositions> pdfPageContentPositions = getPdfContentPostionsList(pdfData);
|
|
|
|
+
|
|
|
|
+ for (PdfPageContentPositions pdfPageContentPosition : pdfPageContentPositions) {
|
|
|
|
+ List<PDFIndexInfo> charPositions = findPositions(keyword,
|
|
|
|
+ pdfPageContentPosition);
|
|
|
|
+ if (charPositions == null || charPositions.size() < 1) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ result.addAll(charPositions);
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * findKeywordPostions
|
|
|
|
+ *
|
|
|
|
+ * @param pdfData
|
|
|
|
+ * @return List<float [ ]> : float[0]:pageNum float[1]:x float[2]:y
|
|
|
|
+ * @throws IOException
|
|
|
|
+ */
|
|
|
|
+ public static List<PDFIndexInfo> findAllwordPostions(byte[] pdfData) throws IOException {
|
|
|
|
+ List<PDFIndexInfo> result = new ArrayList<PDFIndexInfo>();
|
|
|
|
+ List<PdfPageContentPositions> pdfPageContentPositions = getPdfContentPostionsList(pdfData);
|
|
|
|
+
|
|
|
|
+ for (PdfPageContentPositions pdfPageContentPosition : pdfPageContentPositions) {
|
|
|
|
+ PDFIndexInfo pdfIndexInfo = new PDFIndexInfo();
|
|
|
|
+ pdfIndexInfo.setListData(pdfPageContentPosition.getPositions());
|
|
|
|
+ pdfIndexInfo.setPkeyid(pdfPageContentPosition.getContent());
|
|
|
|
+ result.add(pdfIndexInfo);
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ static List<PdfPageContentPositions> getPdfContentPostionsList(
|
|
|
|
+ byte[] pdfData) throws IOException {
|
|
|
|
+ PdfReader reader = new PdfReader(pdfData);
|
|
|
|
+
|
|
|
|
+ List<PdfPageContentPositions> result = new ArrayList<PdfPageContentPositions>();
|
|
|
|
+
|
|
|
|
+ int pages = reader.getNumberOfPages();
|
|
|
|
+ for (int pageNum = 1; pageNum <= pages; pageNum++) {
|
|
|
|
+ float width = reader.getPageSize(pageNum).getWidth();
|
|
|
|
+ float height = reader.getPageSize(pageNum).getHeight();
|
|
|
|
+
|
|
|
|
+ PdfRenderListener pdfRenderListener = new PdfRenderListener(
|
|
|
|
+ pageNum, width, height);
|
|
|
|
+
|
|
|
|
+ // 解析pdf,定位位置
|
|
|
|
+ PdfContentStreamProcessor processor = new PdfContentStreamProcessor(
|
|
|
|
+ pdfRenderListener);
|
|
|
|
+ PdfDictionary pageDic = reader.getPageN(pageNum);
|
|
|
|
+ PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);
|
|
|
|
+ try {
|
|
|
|
+ processor.processContent(ContentByteUtils
|
|
|
|
+ .getContentBytesForPage(reader, pageNum), resourcesDic);
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ reader.close();
|
|
|
|
+ throw e;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String content = pdfRenderListener.getContent();
|
|
|
|
+ List<CharPosition> charPositions = pdfRenderListener
|
|
|
|
+ .getcharPositions();
|
|
|
|
+
|
|
|
|
+ List<float[]> positionsList = new ArrayList<float[]>();
|
|
|
|
+ for (CharPosition charPosition : charPositions) {
|
|
|
|
+ float[] positions = new float[]{charPosition.getPageNum(),
|
|
|
|
+ charPosition.getX(), charPosition.getY()};
|
|
|
|
+ positionsList.add(positions);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ PdfPageContentPositions pdfPageContentPositions = new PdfPageContentPositions();
|
|
|
|
+ pdfPageContentPositions.setContent(content);
|
|
|
|
+ pdfPageContentPositions.setPostions(positionsList);
|
|
|
|
+
|
|
|
|
+ result.add(pdfPageContentPositions);
|
|
|
|
+ }
|
|
|
|
+ reader.close();
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private static List<PDFIndexInfo> findPositions(String keyword,
|
|
|
|
+ PdfPageContentPositions pdfPageContentPositions) {
|
|
|
|
+
|
|
|
|
+ List<PDFIndexInfo> result =new ArrayList<>();
|
|
|
|
+ String content = pdfPageContentPositions.getContent();
|
|
|
|
+ List<float[]> charPositions = pdfPageContentPositions.getPositions();
|
|
|
|
+
|
|
|
|
+ List<String> strList = Func.toStrList(keyword);
|
|
|
|
+ for (String text : strList) {
|
|
|
|
+ for (int pos = 0; pos < content.length(); ) {
|
|
|
|
+ PDFIndexInfo data= new PDFIndexInfo();
|
|
|
|
+ int positionIndex = content.indexOf(text, pos);
|
|
|
|
+ if (positionIndex == -1) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ float[] postions = charPositions.get(positionIndex);
|
|
|
|
+ data.setDataInfo(postions);
|
|
|
|
+ data.setPkeyid(text);
|
|
|
|
+ result.add(data);
|
|
|
|
+ pos = positionIndex + 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private static class PdfPageContentPositions {
|
|
|
|
+ private String content;
|
|
|
|
+ private List<float[]> positions;
|
|
|
|
+
|
|
|
|
+ public String getContent() {
|
|
|
|
+ return content;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void setContent(String content) {
|
|
|
|
+ this.content = content;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public List<float[]> getPositions() {
|
|
|
|
+ return positions;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void setPostions(List<float[]> positions) {
|
|
|
|
+ this.positions = positions;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static class PdfRenderListener implements RenderListener {
|
|
|
|
+ private int pageNum;
|
|
|
|
+ private float pageWidth;
|
|
|
|
+ private float pageHeight;
|
|
|
|
+ private StringBuilder contentBuilder = new StringBuilder();
|
|
|
|
+ private List<CharPosition> charPositions = new ArrayList<CharPosition>();
|
|
|
|
+
|
|
|
|
+ public PdfRenderListener(int pageNum, float pageWidth, float pageHeight) {
|
|
|
|
+ this.pageNum = pageNum;
|
|
|
|
+ this.pageWidth = pageWidth;
|
|
|
|
+ this.pageHeight = pageHeight;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void beginTextBlock() {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void renderText(TextRenderInfo renderInfo) {
|
|
|
|
+ List<TextRenderInfo> characterRenderInfos = renderInfo
|
|
|
|
+ .getCharacterRenderInfos();
|
|
|
|
+ for (TextRenderInfo textRenderInfo : characterRenderInfos) {
|
|
|
|
+ String word = textRenderInfo.getText();
|
|
|
|
+ if (word.length() > 1) {
|
|
|
|
+ word = word.substring(word.length() - 1, word.length());
|
|
|
|
+ }
|
|
|
|
+ com.itextpdf.awt.geom.Rectangle2D.Float rectangle = textRenderInfo.getAscentLine()
|
|
|
|
+ .getBoundingRectange();
|
|
|
|
+ double x = rectangle.getMinX();
|
|
|
|
+ double y = rectangle.getMaxY();
|
|
|
|
+
|
|
|
|
+ float xPercent = Math.round(x / pageWidth * 10000) / 10000f;
|
|
|
|
+ float yPercent = Math.round((1 - y / pageHeight) * 10000) / 10000f;//
|
|
|
|
+
|
|
|
|
+ CharPosition charPosition = new CharPosition(pageNum, xPercent,
|
|
|
|
+ yPercent);
|
|
|
|
+ charPositions.add(charPosition);
|
|
|
|
+ contentBuilder.append(word);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void endTextBlock() {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void renderImage(ImageRenderInfo renderInfo) {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getContent() {
|
|
|
|
+ return contentBuilder.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public List<CharPosition> getcharPositions() {
|
|
|
|
+ return charPositions;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static class CharPosition {
|
|
|
|
+ private int pageNum = 0;
|
|
|
|
+ private float x = 0;
|
|
|
|
+ private float y = 0;
|
|
|
|
+
|
|
|
|
+ public CharPosition(int pageNum, float x, float y) {
|
|
|
|
+ this.pageNum = pageNum;
|
|
|
|
+ this.x = x;
|
|
|
|
+ this.y = y;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public int getPageNum() {
|
|
|
|
+ return pageNum;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public float getX() {
|
|
|
|
+ return x;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public float getY() {
|
|
|
|
+ return y;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public String toString() {
|
|
|
|
+ return "[pageNum=" + this.pageNum + ",x=" + this.x + ",y=" + this.y
|
|
|
|
+ + "]";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static String getNetUrl(String fileUrl){
|
|
|
|
+ String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
|
|
|
|
+ String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
|
|
|
|
+
|
|
|
|
+ String path = sys_file_net_url + fileUrl.replaceAll("//", "/").replaceAll(file_path, "");
|
|
|
|
+ return path;
|
|
|
|
+ }
|
|
|
|
+}
|