如何将8开的影印版PDF试卷变成A4大小的PDF

背景: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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值