【问题标题】:Setting new page size to existing PDF document using Java IText使用 Java IText 将新页面大小设置为现有 PDF 文档
【发布时间】:2016-04-15 22:47:43
【问题描述】:

我想为现有的 PDF 文档设置新的页面大小,而不裁剪内容。我正在编写以下代码,但它只是从底部裁剪我的 PDF 文件,导致内容丢失。

当前尺寸为 8.26" X 11.69",我需要将其设为 8.5" X 11"。

我的代码仅将 11.59 转换为 11。尝试更改 8.26 但它无法正常工作。

有人可以帮忙吗?我正在将 itextpdf-5.5.8 与 Java 一起使用。

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfArray;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfRectangle;
import com.itextpdf.text.pdf.PdfStamper;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;



public class PageSize {

    public static final String SRC = "C:/Temp/BC.pdf";
    public static final String DEST = "C:/Temp/BC_New.pdf";

    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new PageSize().manipulatePdf(SRC, DEST);
    }

    public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        int n = reader.getNumberOfPages();
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        // properties
        PdfContentByte over;
        PdfDictionary pageDict;
        PdfRectangle rect = new PdfRectangle(55, 76, 560, 816);
        PdfArray mediabox;
        float llx, lly, ury,llz;
        // loop over every page
        for (int i = 1; i <= n; i++) {
            pageDict = reader.getPageN(i);
            mediabox = pageDict.getAsArray(PdfName.MEDIABOX);
            llx = mediabox.getAsNumber(0).floatValue();
            lly = mediabox.getAsNumber(1).floatValue();
            llz = mediabox.getAsNumber(2).floatValue();
            ury = mediabox.getAsNumber(3).floatValue();
            mediabox.set(1, new PdfNumber((lly + 50)));
            over = stamper.getOverContent(i);
            over.saveState();
                       over.restoreState();
        }



        stamper.close();
        reader.close();
    }
}

更新 这是我用来将 11.69" 减小到 11" 的代码。它工作正常。但是,它不会将宽度从 8.26 增加到 8.5"

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfArray;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfRectangle;
import com.itextpdf.text.pdf.PdfStamper;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;



public class PageSize {

    public static final String SRC = "C:/Temp/Test.pdf";
    public static final String DEST = "C:/Temp/BC_New.pdf";

    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new PageSize().manipulatePdf(SRC, DEST);
    }

    public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        int n = reader.getNumberOfPages();
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        // properties
        PdfContentByte over;
        PdfDictionary pageDict;
        PdfArray mediabox;
        float llx, lly, ury,llz;
        // loop over every page
        for (int i = 1; i <= n; i++) {
            pageDict = reader.getPageN(i);
            mediabox = pageDict.getAsArray(PdfName.MEDIABOX);
            llx = mediabox.getAsNumber(0).floatValue();
            lly = mediabox.getAsNumber(1).floatValue();
            ury = mediabox.getAsNumber(3).floatValue();
            mediabox.set(0, new PdfNumber((llx - 17)));
            mediabox.set(1, new PdfNumber((lly + 50)));
            over = stamper.getOverContent(i);
            over.saveState();
                       over.restoreState();
        }



        stamper.close();
        reader.close();
    }
}

已解决:

我试图修改的源文件有问题。原始源文件为 8.26" X 11.69"。 hava 程序会在文件中添加徽标并将其保存到新文件中。

不知何故,由于这种转换,新源文件的 X 轴被锁定,因此我的程序无法修改 x 轴。

因此,我将我的程序作为第一步进行了移动,并且成功了。我的程序首先修改 x 和 y 轴,然后将文件传递给另一个程序,该程序执行徽标添加内容。

感谢布鲁诺。 :)

【问题讨论】:

  • 您说“我正在将 iText-2.1.4 与 Java 一起使用。”您的代码显示“import com.itextpdf.text”。这是一个矛盾。您的代码是 iText 5 代码。您不能将它与 iText 2.1.4 一起使用。你甚至不应该使用 iText 2.1.4。欲了解更多信息,请阅读Can iText 2.1.7 or earlier be used commercially?的答案
  • 哦。糟糕的是,我同时放置了两个库,但对我使用的是哪个库感到困惑。更新了我的问题。它的itextpdf-5.5.8。感谢您的回复。对我的代码有什么建议或改进吗?

标签: java pdf-generation itext


【解决方案1】:

您正在更改页面大小而不更改内容。

如果您想缩小内容,那么您需要更复杂的代码。有关示例,请参阅Shrinking the contents of a pdf page。官方文档中也有一个例子:How to shrink pages in an existing PDF?

PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
int n = reader.getNumberOfPages();
PdfDictionary page;
PdfArray crop;
PdfArray media;
for (int p = 1; p <= n; p++) {
    page = reader.getPageN(p);
    media = page.getAsArray(PdfName.CROPBOX);
    if (media == null) {
        media = page.getAsArray(PdfName.MEDIABOX);
    }
    crop = new PdfArray();
    crop.add(new PdfNumber(0));
    crop.add(new PdfNumber(0));
    crop.add(new PdfNumber(media.getAsNumber(2).floatValue() / 2));
    crop.add(new PdfNumber(media.getAsNumber(3).floatValue() / 2));
    page.put(PdfName.MEDIABOX, crop);
    page.put(PdfName.CROPBOX, crop);
    stamper.getUnderContent(p).setLiteral("\nq 0.5 0 0 0.5 0 0 cm\nq\n");
    stamper.getOverContent(p).setLiteral("\nQ\nQ\n");
}
stamper.close();
reader.close();

如果你想放大内容,那么你可以简单地改变UserUnit。更改 UserUnit 在官方文档中也有说明:How to rotate and scale pages in an existing PDF?

float factor = 2.5f;
PdfReader reader = new PdfReader(src);
int n = reader.getNumberOfPages();
PdfDictionary page;
for (int p = 1; p <= n; p++) {
    page = reader.getPageN(p);
    if (page.getAsNumber(PdfName.USERUNIT) == null)
        page.put(PdfName.USERUNIT, new PdfNumber(factor));
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();
reader.close();

此代码会将页面及其内容放大 2.5 倍(因为我们定义为 factor)。

更新

在你的更新中,你有这个:

    mediabox = pageDict.getAsArray(PdfName.MEDIABOX);
    llx = mediabox.getAsNumber(0).floatValue();
    lly = mediabox.getAsNumber(1).floatValue();
    ury = mediabox.getAsNumber(3).floatValue();
    mediabox.set(0, new PdfNumber((llx - 17)));
    mediabox.set(1, new PdfNumber((lly + 50)));

通过这样做,您在x 方向 (llx -17) 上增加了 0.236111 英寸,在y 方向上减少了 0.69445 英寸。如果您说这从 11.69 变为 11 英寸,那么我假设您在谈论 Y 方向。如果原来X方向的宽度是8.26,应该是8.50左右。

我不明白你的问题。当然:我的计算假设您的文档中没有 CropBox。有 CropBox 吗?

【讨论】:

  • 感谢您的代码。我试过了,但它只是缩小了我的页面大小。有没有直接的方法可以先将页面大小设置为 Letter,即 8.5" X 11" 然后继续添加内容?我当前的页面尺寸是 A4,即 8.26" X 11.69"。
  • 要么我不明白你的问题,要么你不明白 PDF。 PDF 页面中的内容是固定的。每个字符在页面上都有固定的位置。您无法更改页面大小并希望内容会重排。 PDF 不是为此而制作的。您将 PDF 与文字处理格式混淆了。
  • 我的理解是,我将采用 A4 大小的 PDF,阅读其内容,创建一个 Letter 大小的新 PDF 文件,将内容添加到其中,内容应该适合。我猜我的假设不够接近。我想要实现的是,我将获得一个 A4 大小的 PDF 文件,并且我想将其制作为具有相同内容和相似布局的 Letter 大小。使用我在原帖中提到的方法,我可以将 11.69 缩小到 11" 但不能缩小到 8.26"。我想如果通过手动执行此操作(forums.adobe.com/thread/1269098?tstart=0)是可行的,为什么不通过代码。
  • 为什么不把我的代码缩小内容和你的代码结合起来改变页面大小?
  • 不幸的是,我的代码只是将 11.69 转换为 11" 而不是 8.26 转换为 8.5"。如果你能帮我解决这个问题,我可以继续将你的代码与我的代码结合起来使其工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
  • 2021-09-23
  • 1970-01-01
  • 2015-12-02
  • 2014-05-31
  • 2011-10-12
  • 1970-01-01
相关资源
最近更新 更多