如何使用 PDFBox 将文本居中

发布于 2024-11-17 10:28:56 字数 251 浏览 4 评论 0原文

我的问题很简单:如何使用 PDFBox 将文本放在 PDF 上?

我事先不知道字符串,我无法通过尝试找到中间。字符串并不总是具有相同的宽度。

我需要:

  • 一种可以使文本居中的方法,例如 addCenteredString(myString)
  • 一种可以为我提供字符串宽度(以像素为单位)的方法。然后我可以计算中心,因为我知道 PDF 的尺寸。

欢迎任何帮助!

My question is very simple: how can I center a text on a PDF, using PDFBox?

I don't know the string in advance, I can't find the middle by trial. The string doesn't always have the same width.

I need either:

  • A method that can center the text, something like addCenteredString(myString)
  • A method that can give me the width of the string in pixels. I can then calculate the center, for I know the dimensions of the PDF.

Any help is welcome!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

谁与争疯 2024-11-24 10:28:56

好吧,我自己找到了答案。以下是如何将页面上的某些文本居中:

String title = "This is my wonderful title!"; // Or whatever title you want.
int marginTop = 30; // Or whatever margin you want.

PDDocument document = new PDDocument();
PDPage page = new PDPage();
PDPageContentStream stream = new PDPageContentStream(document, page);
PDFont font = PDType1Font.HELVETICA_BOLD; // Or whatever font you want.

int fontSize = 16; // Or whatever font size you want.
float titleWidth = font.getStringWidth(title) / 1000 * fontSize;
float titleHeight = font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize;

stream.beginText();
stream.setFont(font, fontSize);
// Deprecated, only before 2.0:
// stream.moveTextPositionByAmount((page.getMediaBox().getWidth() - titleWidth) / 2, page.getMediaBox().getHeight() - marginTop - titleHeight);
// From 2.0 and beyond:
stream.newLineAtOffset((page.getMediaBox().getWidth() - titleWidth) / 2, page.getMediaBox().getHeight() - marginTop - titleHeight);
stream.drawString(title);
stream.endText();
stream.close();

Ok, I found the answer myself. Here is how to center some text on a page:

String title = "This is my wonderful title!"; // Or whatever title you want.
int marginTop = 30; // Or whatever margin you want.

PDDocument document = new PDDocument();
PDPage page = new PDPage();
PDPageContentStream stream = new PDPageContentStream(document, page);
PDFont font = PDType1Font.HELVETICA_BOLD; // Or whatever font you want.

int fontSize = 16; // Or whatever font size you want.
float titleWidth = font.getStringWidth(title) / 1000 * fontSize;
float titleHeight = font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize;

stream.beginText();
stream.setFont(font, fontSize);
// Deprecated, only before 2.0:
// stream.moveTextPositionByAmount((page.getMediaBox().getWidth() - titleWidth) / 2, page.getMediaBox().getHeight() - marginTop - titleHeight);
// From 2.0 and beyond:
stream.newLineAtOffset((page.getMediaBox().getWidth() - titleWidth) / 2, page.getMediaBox().getHeight() - marginTop - titleHeight);
stream.drawString(title);
stream.endText();
stream.close();
明媚如初 2024-11-24 10:28:56

这会将居中文本添加到纵向和横向格式的页面:

void addCenteredText(String text, PDFont font, int fontSize, PDPageContentStream content, PDPage page, Point2D.Float offset) throws IOException {
    content.setFont(font, fontSize);
    content.beginText();

    // Rotate the text according to the page orientation
    boolean pageIsLandscape = isLandscape(page);
    Point2D.Float pageCenter = getCenter(page);

    // We use the text's width to place it at the center of the page
    float stringWidth = getStringWidth(text, font, fontSize);
    if (pageIsLandscape) {
        float textX = pageCenter.x - stringWidth / 2F + offset.x;
        float textY = pageCenter.y - offset.y;
        // Swap X and Y due to the rotation
        content.setTextMatrix(Matrix.getRotateInstance(Math.PI / 2, textY, textX));
    } else {
        float textX = pageCenter.x - stringWidth / 2F + offset.x;
        float textY = pageCenter.y + offset.y;
        content.setTextMatrix(Matrix.getTranslateInstance(textX, textY));
    }

    content.showText(text);
    content.endText();
}

boolean isLandscape(PDPage page) {
    int rotation = page.getRotation();
    final boolean isLandscape;
    if (rotation == 90 || rotation == 270) {
        isLandscape = true;
    } else if (rotation == 0 || rotation == 360 || rotation == 180) {
        isLandscape = false;
    } else {
        LOG.warn("Can only handle pages that are rotated in 90 degree steps. This page is rotated {} degrees. Will treat the page as in portrait format", rotation);
        isLandscape = false;
    }
    return isLandscape;
}

Point2D.Float getCenter(PDPage page) {
    PDRectangle pageSize = page.getMediaBox();
    boolean rotated = isLandscape(page);
    float pageWidth = rotated ? pageSize.getHeight() : pageSize.getWidth();
    float pageHeight = rotated ? pageSize.getWidth() : pageSize.getHeight();

    return new Point2D.Float(pageWidth / 2F, pageHeight / 2F);
}

float getStringWidth(String text, PDFont font, int fontSize) throws IOException {
    return font.getStringWidth(text) * fontSize / 1000F;
}

这是在旋转页面上创建居中文本的 PDF 的方法:

PDDocument pdf = new PDDocument();
// A5 page in landscape format
PDPage page = new PDPage(PDRectangle.A5);
page.setRotation(90);

pdf.addPage(page);
try (PDPageContentStream content = new PDPageContentStream(pdf, page)) {
    int fontSize = 36;

    // Put the text at the page's center, no offset
    Point2D.Float center = new Point2D.Float(0, 0);
    addCenteredText("PDFBox", PDType1Font.HELVETICA_BOLD, fontSize, content, page, center);

    // Put the text centered at the lower end of the page
    Point2D.Float lowerCenter = new Point2D.Float(0, -165);
    addCenteredText("Hi there!", PDType1Font.HELVETICA, fontSize, content, page, lowerCenter);

} catch (IOException e) {
    LOG.warn("Exception while creating content", e);
}

生成的 PDF:

resulting PDF

我使用 PDFBox 2.0.0-RC2 创建此 PDF 。

This adds centered text to pages in portrait as well as landscape format:

void addCenteredText(String text, PDFont font, int fontSize, PDPageContentStream content, PDPage page, Point2D.Float offset) throws IOException {
    content.setFont(font, fontSize);
    content.beginText();

    // Rotate the text according to the page orientation
    boolean pageIsLandscape = isLandscape(page);
    Point2D.Float pageCenter = getCenter(page);

    // We use the text's width to place it at the center of the page
    float stringWidth = getStringWidth(text, font, fontSize);
    if (pageIsLandscape) {
        float textX = pageCenter.x - stringWidth / 2F + offset.x;
        float textY = pageCenter.y - offset.y;
        // Swap X and Y due to the rotation
        content.setTextMatrix(Matrix.getRotateInstance(Math.PI / 2, textY, textX));
    } else {
        float textX = pageCenter.x - stringWidth / 2F + offset.x;
        float textY = pageCenter.y + offset.y;
        content.setTextMatrix(Matrix.getTranslateInstance(textX, textY));
    }

    content.showText(text);
    content.endText();
}

boolean isLandscape(PDPage page) {
    int rotation = page.getRotation();
    final boolean isLandscape;
    if (rotation == 90 || rotation == 270) {
        isLandscape = true;
    } else if (rotation == 0 || rotation == 360 || rotation == 180) {
        isLandscape = false;
    } else {
        LOG.warn("Can only handle pages that are rotated in 90 degree steps. This page is rotated {} degrees. Will treat the page as in portrait format", rotation);
        isLandscape = false;
    }
    return isLandscape;
}

Point2D.Float getCenter(PDPage page) {
    PDRectangle pageSize = page.getMediaBox();
    boolean rotated = isLandscape(page);
    float pageWidth = rotated ? pageSize.getHeight() : pageSize.getWidth();
    float pageHeight = rotated ? pageSize.getWidth() : pageSize.getHeight();

    return new Point2D.Float(pageWidth / 2F, pageHeight / 2F);
}

float getStringWidth(String text, PDFont font, int fontSize) throws IOException {
    return font.getStringWidth(text) * fontSize / 1000F;
}

This is how you create a PDF with centered text on a rotated page:

PDDocument pdf = new PDDocument();
// A5 page in landscape format
PDPage page = new PDPage(PDRectangle.A5);
page.setRotation(90);

pdf.addPage(page);
try (PDPageContentStream content = new PDPageContentStream(pdf, page)) {
    int fontSize = 36;

    // Put the text at the page's center, no offset
    Point2D.Float center = new Point2D.Float(0, 0);
    addCenteredText("PDFBox", PDType1Font.HELVETICA_BOLD, fontSize, content, page, center);

    // Put the text centered at the lower end of the page
    Point2D.Float lowerCenter = new Point2D.Float(0, -165);
    addCenteredText("Hi there!", PDType1Font.HELVETICA, fontSize, content, page, lowerCenter);

} catch (IOException e) {
    LOG.warn("Exception while creating content", e);
}

The resulting PDF:

resulting PDF

I used PDFBox 2.0.0-RC2 for creating this PDF.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文