背景:8开的试卷是不能在家用打印机中打印的,因为家用打印机只能支持A4排版
解决办法:将8开的试卷分割为两个A4
思路:抽取PDF页为图片,将图片进行水平分割,再将图片合并成新的PDF。
相关代码:
1、将PDF文件转换成一个个图片文件,
使用pdfbox,将PDF中的页-》图片
public static void pdf2img(String filename, String extension) throws IOException {
@Cleanup
PDDocument document = Loader.loadPDF(new File(filename));
(new File("pngs")).mkdir();
PDFRenderer pdfRenderer = new PDFRenderer(document);
for (int page = 0; page < document.getNumberOfPages(); ++page) {
BufferedImage bim = pdfRenderer.renderImageWithDPI(
page, 300, ImageType.RGB);
String imgfilename = String.format("pngs/pdf-%03d.%s", page + 1, extension);
ImageIOUtil.writeImage(
bim, imgfilename, 300);
log.info("export {} page {} to {} ", filename, page + 1, imgfilename);
}
}
其中每页使用%03d,即三位的数字来表示,这样后面合并新的pdf时,可使用图片文件名排序。
2、将图片进行水平分割
public static void images8k2parts(String dir, String extension) throws IOException {
(new File("pngs2")).mkdir();
File[] files = (new File(dir)).listFiles();
for (File file : files) {
BufferedImage bufferedImage = ImageIO.read(file);
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
for (int i = 0; i < 2; i++) {
int x = i == 0 ? 0 : (int) (width * 0.5f);
BufferedImage image = bufferedImage.getSubimage(x, 0, width / 2, height);
ImageIOUtil.writeImage(
image, String.format("pngs2/%s-%03d.%s", file.getName(), i, extension), 300);
}
log.info("convert img 8k to two parts {}", file.getName());
}
}
转上面的所有图片,逐个分割成两个,其中新文件用00,01来追加命名。
3、再将图片合并成新的PDF
public static void images2pdf(String dir, String extension) throws FileNotFoundException, MalformedURLException {
File[] files = (new File(dir)).listFiles();
Arrays.sort(files, Comparator.comparing(File::getName));
String output = dir + "merged.pdf";
PdfWriter writer = new PdfWriter(output);
PdfDocument pdfDoc = new PdfDocument(writer);
@Cleanup
Document document = new Document(pdfDoc);
document.setMargins(0, 0, 0, 0);
for (File file : files) {
if (file.getName().endsWith(extension)) {
ImageData data = ImageDataFactory.create(file.getAbsolutePath());
Image image = new Image(data);
image.setAutoScaleHeight(true);
image.setAutoScaleWidth(true);
document.add(image);
}
}
}
新的pdf文件就生成OK了。
依赖的库包:
--pom.xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.1.0-alpha1</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>kernel</artifactId>
<version>8.0.3</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>io</artifactId>
<version>8.0.3</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>layout</artifactId>
<version>8.0.3</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-tools</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
</dependency>