场景:根据模板生成对应票据pdf后,因pdf留白过多导致针式打印机打印出的文件占比过小,故需要裁剪pdf白边使之可以适配打印场景。
思路:本来想的是将pdf先转换成图片,然后对图片裁剪再转换回pdf,发现该情况会导致打印出的pdf质量变低,故改为直接裁剪pdf。下面直接贴代码。
对应依赖:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>3.0.0</version>
</dependency>
对应工具类:
package com.t.module.fee.util;
import cn.hutool.core.io.FileUtil;
import com.aspose.cells.PaperSizeType;
import com.aspose.cells.PdfCompliance;
import com.aspose.cells.PdfSaveOptions;
import com.aspose.cells.Workbook;
import com.xtfintek.framework.security.core.util.SecurityFrameworkUtils;
import lombok.experimental.UtilityClass;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
/**
* excel转pdf
*
* @author hch
* @since 2024/06/06 11:15
*/
@UtilityClass
public class ExportUtil {
private static final Logger log = LoggerFactory.getLogger(ExportUtil.class);
/**
* excel转PDF
*
* @param file excel文件
* @return 字节数组
*/
public static byte[] excelToPdfByIou(File file) {
ByteArrayOutputStream excelToPdfOs = new ByteArrayOutputStream();
try (BufferedInputStream inputStream = FileUtil.getInputStream(file)) {
Workbook workbook = new Workbook(inputStream);
// 设置纸张大小
workbook.getSettings().setPaperSize(PaperSizeType.PAPER_15_X_11);
// 设置PDF保存选项
PdfSaveOptions options = new PdfSaveOptions();
options.setPdfCompression(0);
options.setCompliance(PdfCompliance.PDF_A_1_B);
options.setOnePagePerSheet(true);
// 保存为PDF到输出流
workbook.save(excelToPdfOs, options);
croppingPdf(excelToPdfOs);
return excelToPdfOs.toByteArray();
} catch (Exception e) {
throw new RuntimeException("Error converting Excel to PDF", e);
} finally {
try {
excelToPdfOs.flush();
excelToPdfOs.close();
} catch (IOException ignored) {
log.error("pdf制作,文件流关闭失败");
}
}
}
/**
* 裁剪pdf
*
* @param excelToPdfOs 待转换文件流
*/
public static void croppingPdf(ByteArrayOutputStream excelToPdfOs) {
PDDocument pdDocument;
try {
pdDocument = Loader.loadPDF(excelToPdfOs.toByteArray());
PDPage page = pdDocument.getPage(0);
PDRectangle rectangle = page.getMediaBox();
rectangle.setUpperRightX(rectangle.getWidth() * 0.85f);
rectangle.setUpperRightY(rectangle.getHeight());
page.setCropBox(rectangle);
page.setMediaBox(rectangle);
excelToPdfOs.flush();
pdDocument.save(excelToPdfOs);
pdDocument.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}