【问题标题】:How to center a text using PDFBox如何使用 PDFBox 使文本居中
【发布时间】:2011-09-24 07:52:20
【问题描述】:

我的问题很简单:如何使用PDFBox 使 PDF 上的文本居中?

事先不知道字符串,试了也找不到中间。字符串并不总是具有相同的宽度。

我需要:

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

欢迎任何帮助!

【问题讨论】:

    标签: java pdfbox text-alignment


    【解决方案1】:

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

    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();
    

    【讨论】:

    • 请注意,如果页面被旋转(即设置为横向模式)page.getMediaBox().getHeight() 应替换为 page.getMediaBox().getHeight(),如 getMediaBox( ) 没有考虑到页面是旋转的。
    • 为什么 pdfbox 的文档中没有这些信息?!他们有一个字体示例,但没有对高度做任何事情。另外,为什么我们需要记住除以 1000 并乘以 fontSize?那是怎么回事?只需让我们成为 PDFont 上的辅助方法!为什么文档中没有解释?最后一条评论听起来很有帮助,但它说用 X 替换 X。我希望 hanspeide 能跟进澄清。
    • @chubbsondubs from javadocs pdfbox.apache.org/apidocs/org/apache/pdfbox/pdmodel/font/… 返回:字符串在 1000 个文本空间单位中的宽度,即 333 567...
    • 你在stream.beginText();之后忘记了stream.setFont(font, fontSize);吗? Hesham 建议修复,但它 was rejected.
    • @SteeveDroz 是的,是的
    【解决方案2】:

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

    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:

    我使用 PDFBox 2.0.0-RC2 来创建这个 PDF。

    【讨论】:

      猜你喜欢
      • 2013-10-19
      • 2013-10-12
      • 1970-01-01
      • 1970-01-01
      • 2014-10-04
      • 2016-09-30
      • 2015-07-13
      • 1970-01-01
      • 2014-07-11
      相关资源
      最近更新 更多