使用 PDFBox 将文本写入多边形

发布于 2024-12-15 16:06:25 字数 2360 浏览 1 评论 0原文

我发现了如何使用drawText将文本写入页面,并且使用drawPolygon将多边形显示在正确的位置。

问题是,当我只绘制文本时它可以工作,但是一旦我绘制多边形,文本就不再绘制。

如果我创建两个 PDPageContentStream 对象(一个用于文本,另一个用于多边形),则不再绘制多边形。

这是我的测试课。任何 PDF 都应该用于测试。

    package ch.sertal.vision.server.helpers;

import ch.sertal.vision.BaseDaoTest;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.testng.annotations.Test;

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

/**
 * Created by IntelliJ IDEA.
 * User: micha.roon
 * Date: 11/13/11
 * Time: 11:22 PM
 * To change this template use File | Settings | File Templates.
 */
public class WritePDFTest extends BaseDaoTest {

   @Test
   public void testTextPlacement() throws IOException, COSVisitorException, URISyntaxException {
      File pdfFile = new File( this.getClass().getResource( "/META-INF/menge-regierapport.pdf" ).toURI() );
      PDDocument doc = PDDocument.load( pdfFile );
      PDPage page = null;
      for ( Object kid : doc.getDocumentCatalog().getPages().getKids() ) {
         if ( kid instanceof PDPage ) {
            page = ( PDPage ) kid;
            break;
         }
      }
      PDPageContentStream rectContent = new PDPageContentStream( doc, page, true, false );
      rectContent.setNonStrokingColor( Color.blue );

      PDPageContentStream content = new PDPageContentStream( doc, page, true, false );

      writeOnPage( content, String.valueOf( page.getArtBox().getHeight() ), 0, 0 );
      writeOnPage( content, String.valueOf( page.getArtBox().getWidth() ), 200, 100 );
      rectContent.fillRect( 100, 200, 100, 50 );
      content.close();
      doc.save( new FileOutputStream(
                  new File( this.getClass().getResource( "/META-INF/menge-regierapport.pdf" ).toURI() )) );
      doc.close();
   }

   void writeOnPage(PDPageContentStream content, String text, int x, int y) throws IOException {
      content.beginText();
      content.setFont( PDType1Font.HELVETICA, 10 );
      content.moveTextPositionByAmount( x, y );
      content.drawString( text );
      content.endText();
   }

}

感谢您的帮助

I found out how to write text onto the page with drawText and the polygon appears at the right place with drawPolygon.

The issue is that when I just draw text it works but as soon as I draw the polygons, the text is not drawn anymore.

If I create two PDPageContentStream objects (one for the text and another for the polygon) the polygons are not drawn anymore.

Here is my test class. Any PDF should do for testing.

    package ch.sertal.vision.server.helpers;

import ch.sertal.vision.BaseDaoTest;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.testng.annotations.Test;

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

/**
 * Created by IntelliJ IDEA.
 * User: micha.roon
 * Date: 11/13/11
 * Time: 11:22 PM
 * To change this template use File | Settings | File Templates.
 */
public class WritePDFTest extends BaseDaoTest {

   @Test
   public void testTextPlacement() throws IOException, COSVisitorException, URISyntaxException {
      File pdfFile = new File( this.getClass().getResource( "/META-INF/menge-regierapport.pdf" ).toURI() );
      PDDocument doc = PDDocument.load( pdfFile );
      PDPage page = null;
      for ( Object kid : doc.getDocumentCatalog().getPages().getKids() ) {
         if ( kid instanceof PDPage ) {
            page = ( PDPage ) kid;
            break;
         }
      }
      PDPageContentStream rectContent = new PDPageContentStream( doc, page, true, false );
      rectContent.setNonStrokingColor( Color.blue );

      PDPageContentStream content = new PDPageContentStream( doc, page, true, false );

      writeOnPage( content, String.valueOf( page.getArtBox().getHeight() ), 0, 0 );
      writeOnPage( content, String.valueOf( page.getArtBox().getWidth() ), 200, 100 );
      rectContent.fillRect( 100, 200, 100, 50 );
      content.close();
      doc.save( new FileOutputStream(
                  new File( this.getClass().getResource( "/META-INF/menge-regierapport.pdf" ).toURI() )) );
      doc.close();
   }

   void writeOnPage(PDPageContentStream content, String text, int x, int y) throws IOException {
      content.beginText();
      content.setFont( PDType1Font.HELVETICA, 10 );
      content.moveTextPositionByAmount( x, y );
      content.drawString( text );
      content.endText();
   }

}

Thank you for your help

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

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

发布评论

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

评论(2

长发绾君心 2024-12-22 16:06:25
  1. 您的主要问题是您从不调用 rectContent.close() 。
  2. 看起来 rectContentcontent 实际上是指向同一个“流”的指针,重新编写代码以解决 PDFBox 的实际工作方式可能是有意义的。这意味着 (a) 删除 rectContent 并将其替换为 content

    PDPageContentStream content = new PDPageContentStream( doc, page, true, false );
    content.setNonStrokingColor( Color.blue );
    
    // 将其移到内容之前,因此它写在“下面”(我认为)
    内容.fillRect( 100, 200, 100, 50 );
    
    // 将颜色重置为黑色
    content.setNonStrokingColor( Color.black );
    
    writeOnPage( 内容, String.valueOf( page.getArtBox().getHeight() ), 0, 0 );
    writeOnPage( 内容, String.valueOf( page.getArtBox().getWidth() ), 200, 100 );
    内容.关闭();
    doc.save( 新的 FileOutputStream(
          new File( this.getClass().getResource( "/META-INF/menge-regierapport.pdf" ).toURI() )) );
    文档.关闭();
    
  1. your main issue is that you never call rectContent.close().
  2. It appears that rectContent and content are actually pointers to the same "stream" and it may make sense to rework the code to address how PDFBox is actually working. This would mean (a) removing rectContent and replacing it with content.

    PDPageContentStream content = new PDPageContentStream( doc, page, true, false );
    content.setNonStrokingColor( Color.blue );
    
    // moving this before content, so it's written "below" (I think)
    content.fillRect( 100, 200, 100, 50 );
    
    // resetting the color to black
    content.setNonStrokingColor( Color.black );
    
    writeOnPage( content, String.valueOf( page.getArtBox().getHeight() ), 0, 0 );
    writeOnPage( content, String.valueOf( page.getArtBox().getWidth() ), 200, 100 );
    content.close();
    doc.save( new FileOutputStream(
          new File( this.getClass().getResource( "/META-INF/menge-regierapport.pdf" ).toURI() )) );
    doc.close();
    
无法回应 2024-12-22 16:06:25

我认为当你绘制矩形和文本时 setNonStrokingColor 是相同的。所以矩形将隐藏文本。解决方案是调用 setNonStrokingColor 并为 Rect 和文本指定不同的值。那么你应该能够看到他们两个。

I think the setNonStrokingColor is the same when you draw the Rect and the text. So the Rect will hide the text. The solution is to call setNonStrokingColor with different values for the Rect and the text. Then you should be able to see both of them.

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