根据PDF文件尺寸计算印章缩放比例

更新时间:2025-11-25 14:06:46

背景

文件非A4大小尺寸的情况下,想要实现最终以A4大小文件打印出来时,印章大小与预期大小保持一致,即印章大小与文件尺寸进行等比例缩放。


处理逻辑

1、获取A4对应PDF页面尺寸信息widthTpl、heightTpl,获取当前文件实际的尺寸信息widthReal、heightReal,定义默认印章尺寸

2、计算印章缩放比例(与A4进行比较), 需注意:竖向文件缩放比例取widthReal / widthTpl ,横向文widthReal / heightTpl

3、实际需设置的印章尺寸 = 默认印章尺寸 * 缩放比例

代码片段

JAVA版本
package cn.hz.itechsign.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;

public class ScalingPrintDemo {

    private static float pageOriginalWidth;
    private static float pageOriginalHeight;
    private static float pageVisibleWidth;
    private static float pageVisibleHeight;

    public static void main(String[] args) {
        String filePath = "pdf" + File.separator + "A2.pdf";
        try {

            // 获取PDF页面尺寸信息
            getPageSize(filePath);
            // 计算印章缩放比例
            float sealScaling = calculateSealScaling(pageOriginalWidth, pageVisibleWidth, pageVisibleHeight, filePath);
            // 默认印章大小
            float sealWidth = 159.00F;
            if (sealScaling > 0) {
                // 等比缩放后印章大小
                float sealScalingWidth = sealWidth * sealScaling;
                System.out.println("印章原始宽度为:" + sealWidth + ", 印章缩放后宽度为:" + sealScalingWidth);
                System.out.println("若缩放到A4打印则签署时需传入的印章Width为:" + sealScalingWidth);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    /***
	 * 获取页面尺寸信息
	 * 
	 * @param srcPdfPath
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws DocumentException
	 */
    public static void getPageSize(String srcPdfPath) throws FileNotFoundException, IOException, DocumentException {
        PdfReader reader = new PdfReader(new FileInputStream(new File(srcPdfPath)));
        // PDF页码
        int pageNum = 1;

        // PDF页面原始(实际)宽度大小
        pageOriginalWidth = reader.getPageSize(1).getWidth();
        // PDF页面原始(实际)高度大小
        pageOriginalHeight = reader.getPageSize(1).getHeight();

        PdfStamper stamper = new PdfStamper(reader, null);
        PdfContentByte content = stamper.getOverContent(pageNum);

        Rectangle rectangle = content.getPdfDocument().getPageSize();
        // 页面视图宽度
        pageVisibleWidth = rectangle.getWidth();
        // 页面视图高度
        pageVisibleHeight = rectangle.getHeight();
        // 页面实际大小就是页面的实际大小
        System.out.println("页面实际宽度大小为:" + pageOriginalWidth + ", 页面实际高度大小为:" + pageOriginalHeight);
        // 页面视图大小就是Adobe Reader 软件中肉眼可见的页面区域(也是缩放后的可见区域)
        System.out.println("页面视图宽度大小为:" + pageVisibleWidth + ", 页面视图高度大小为:" + pageVisibleHeight);
    }

    /**
	 * 判断是否为横向文件
	 * 
	 * @param srcPdfPath
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws DocumentException
	 */

    public static boolean getHengxiang(PdfReader reader) throws FileNotFoundException, IOException, DocumentException {
        Rectangle currentPageRectangle = reader.getPageSizeWithRotation(1);
        if (currentPageRectangle.getWidth() > currentPageRectangle.getHeight()) {
            System.out.println("这是一个横向文件");// 横向文件
            return true;
        }
        System.out.println("这是一个竖向文件");// 竖向文件
        return false;// 竖向文件

    }

    /***
	 * 计算印章缩放比例
	 * 
	 * @param pageOriginalWidth
	 * @param pageVisibleWidth
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws DocumentException
	 */
public static float calculateSealScaling(float pageOriginalWidth, float pageVisibleWidth, float pageVisibleHeight,
String filePath) throws FileNotFoundException, IOException, DocumentException {
// 印章缩放比例
float sealScaling = 0.0F;
PdfReader reader = new PdfReader(new FileInputStream(new File(filePath)));
// PDF页码
getHengxiang(reader); // 判断横竖 0-横向 1-竖向
if (getHengxiang(reader)) {// 横向文件宽度数值对应是普通A4的高度
if (pageOriginalWidth > pageVisibleHeight) {
// 印章缩放比例
sealScaling = pageOriginalWidth / pageVisibleHeight;
}
} else if (pageOriginalWidth > pageVisibleWidth) {// 印章缩放比例
sealScaling = pageOriginalWidth / pageVisibleWidth;
}
// 如果原始(实际)页面大小大于页面视图大小计算印章缩放比例
System.out.println("印章缩放比例为:" + sealScaling);
return sealScaling;

}

}

PHP版本

通过FPDI库来实现计算PDF尺寸,以及横向还是竖向。与A4文件尺寸比较,计算入参里需设置的印章大小。

<?php
require(__DIR__.'/fpdf181/fpdf.php');
require_once(__DIR__.'/FPDI-2.3.7/src/autoload.php');
ini_set("display_errors", "stderr");error_reporting(E_ALL);
//test();
main(); 
$pageOriginalWidth=0; $pageVisibleWidth=0; $pageVisibleHeight=0;$orientation="";
function main()
{

  $filePath = "pdf" . DIRECTORY_SEPARATOR . "A2.pdf";
  try {
    global $pageOriginalWidth, $pageVisibleWidth, $pageVisibleHeight,$orientation;
    // 获取PDF页面尺寸信息
    getPageSize($filePath);
    // 计算印章缩放比例
    $sealScaling = calculateSealScaling($pageOriginalWidth, $pageVisibleWidth, $pageVisibleHeight, $orientation);
    // 默认印章大小
    $sealWidth = 200.00;
    if ($sealScaling > 0) {
      // 等比缩放后印章大小
      $sealScalingWidth = $sealWidth * $sealScaling;
      echo "印章原始宽度为:" . $sealWidth . ", 印章缩放后宽度为:" . $sealScalingWidth . PHP_EOL;
      echo "若缩放到A4打印则签署时需传入的印章Width为:" . $sealScalingWidth . PHP_EOL;
    }
  } catch (IOException $e) {
    echo $e->getMessage() . PHP_EOL;
  } catch (DocumentException $e) {
    echo $e->getMessage() . PHP_EOL;
  }
}

/**
* 获取页面尺寸信息
*
* @param string $srcPdfPath
* @throws \Exception
*/
function getPageSize($srcPdfPath) {
  global $pageOriginalWidth, $pageVisibleWidth, $pageVisibleHeight,$orientation;

  $pdf = new \setasign\Fpdi\FPDI('P','pt');
  // add a page
  $pdf->AddPage();
  // set the source file
  $pdf->setSourceFile($srcPdfPath);

  // PDF页码
  $pageNum = 1;
  $tplId = $pdf->importPage($pageNum);
  $size = $pdf->getTemplateSize($tplId);// L是横版,P是竖版
  //     array(5) { ["width"]=> int(1240) ["height"]=> int(1584) [0]=> int(1240) [1]=> int(1584) ["orientation"]=> string(1) "P" }
  $pageOriginalWidth = $size["width"];  //PDF页面原始(实际)宽度大小
  $pageOriginalHeight = $size["height"]    ;   //PDF页面原始(实际)高度大小
  $orientation = $size["orientation"] ;

  // 页面视图宽度【A4尺寸】
  $pageVisibleWidth = $pdf->GetPageWidth();
  // 页面视图高度
  $pageVisibleHeight = $pdf->GetPageHeight();
  // 页面实际大小就是页面的实际大小
  echo "页面实际宽度大小为:" . $pageOriginalWidth . ", 页面实际高度大小为:" . $pageOriginalHeight . PHP_EOL;
  // 页面视图大小就是Adobe Reader 软件中肉眼可见的页面区域(也是缩放后的可见区域)
  echo "页面视图宽度大小为:" . $pageVisibleWidth . ", 页面视图高度大小为:" . $pageVisibleHeight . PHP_EOL;
}


function calculateSealScaling($pageOriginalWidth, $pageVisibleWidth, $pageVisibleHeight, $orientation) {
  $sealScaling = 0.0;
  if ($orientation == "L") { // 横向文件宽度数值对应是普通A4的高度
      echo "这个是横向文件" .PHP_EOL;
      if ($pageOriginalWidth > $pageVisibleHeight) {
        // 印章缩放比例
        $sealScaling = $pageOriginalWidth / $pageVisibleHeight;
      }
     } elseif ($pageOriginalWidth > $pageVisibleWidth) { // 印章缩放比例
         echo "这个是竖向文件" .PHP_EOL;
  		   $sealScaling = $pageOriginalWidth / $pageVisibleWidth;
     }
    // 如果原始(实际)页面大小大于页面视图大小计算印章缩放比例
  echo "印章缩放比例为:" . $sealScaling;
  return $sealScaling;
}

运行结果

我要纠错