2011-07-08 47 views
3

我的要求是要求生成包含任意文本和条形码的pdf文档。我有相关的question地址pdf生成的一部分,但在这里我想知道如何在Java中的PDF中加入条形码。如何使用生成将整合动态生成条形码(Java)的pdf文档?

到目前为止,我发现在barcode4j是怎么做的与Apache FOP明确的解释:Instructions for the Apache FOP extension

但它看起来是XSL-FO是不是我要求的主要选择,我宁愿去与PDF表单(使用iText或PDFBox或类似)。再次,这还不是最终的。

您是否在pdf中使用图像或字体作为条形码?除了pdf API以外,还有什么依赖性(字体,库)?

回答

1

我会使用条形码图像生成器,然后将其嵌入到转换为PDF的HTML文档中。

检出this library用于将XHTML呈现为PDF。按照您最初的计划,使用barcode4j将条形码呈现为图像。

+0

然而,这不是免费的:它需要iText的,将要求在商业许可我的情况。 – topchef

+0

这是GPL3。除非你需要表扬,否则它不需要商业许可证。 –

1

如果你准备放松你生成PDF要求使用非Java的工具,你可能会发现以下有用的:

  1. 布局使用HTML/CSS/JS与占位符条形码的页面模板。
  2. 使用Barcode4J至output SVG,然后将其放入模板中。
  3. 使用wkhtmltopdf命令行工具呈现页面。 wkhtmltopdf在引擎盖下使用了WebKit,因此它使用HTML/CSS可以很好地控制PDF布局。
2

为了在PDF中生成条码我强烈建议iText给你。如果你使用Maven的,您可以添加这些依赖关系,你可以开始:

<dependency> 
     <groupId>com.lowagie</groupId> 
     <artifactId>itext</artifactId> 
     <version>2.0.7</version> 
    </dependency> 
    <dependency> 
     <groupId>bouncycastle</groupId> 
     <artifactId>bcmail-jdk14</artifactId> 
     <version>136</version> 
    </dependency> 
    <dependency> 
     <groupId>bouncycastle</groupId> 
     <artifactId>bcprov-jdk14</artifactId> 
     <version>136</version> 
    </dependency> 

要生成条形码需要的代码只有几行:

Barcode128 code128 = new Barcode128(); 
    code128.setCodeType(Barcode128.CODE128); 
    code128.setCode(new Long(1234559690234234); 
    Chunk chunk = new Chunk(code128.createImageWithBarcode(cb, null, null), 
      200, -30); 
    Paragraph p = new Paragraph(chunk); 

添加段落到文档,瞧,你去了。一个好的教程可以在这里找到:

IText Example

+0

谢谢,绝对会试试看。 – topchef

5

我成功地将条形码使用PDFBox的和烧烤的PDF文件。烧烤提供输出接口来自己绘制条形码。我以这样的方式实现了这个接口,drawBar()转换为对PDPageContentStream.fillRect()的调用。

添加条形码到PDF现在归结为:

Barcode barcode = BarcodeFactory.createCode128(text); 
barcode.output(new PDFBoxOutput(pageContentStream, startX, startY, height)); 

的PDFBoxOutput类看起来是这样的:

import java.awt.Color; 
import java.io.IOException; 

import net.sourceforge.barbecue.output.LabelLayout; 
import net.sourceforge.barbecue.output.Output; 
import net.sourceforge.barbecue.output.OutputException; 

import org.apache.pdfbox.pdmodel.edit.PDPageContentStream; 

public class PDFBoxOutput implements Output { 

    /** The widths and heights from Barbecue are multipplied with this scalar to get the widths and heights for PDFBox. */ 
    public final static float SCALAR = 0.5f; 

    private final PDPageContentStream stream; 
    private final float startX; 
    private final float startY; 
    private final float height; 
    private boolean toggleDrawingColor; 

    PDFBoxOutput(PDPageContentStream stream, float startX, float startY, float height) { 
     this.stream = stream; 
     this.startX = startX; 
     this.startY = startY; 
     this.height = height; 
    } 

    @Override 
    public void beginDraw() throws OutputException {} 

    @Override 
    public int drawBar(int x, int y, int width, int height, boolean paintWithForegroundColor) throws OutputException { 
     if (paintWithForegroundColor == !toggleDrawingColor) { 
      try { 
       stream.setLineWidth(0.0f); 
       stream.setStrokingColor(Color.BLACK); 
       stream.fillRect(startX + SCALAR * x, startY - SCALAR * y, SCALAR * width, this.height); 
       stream.stroke(); 
      } catch (IOException e) { 
       throw new OutputException(e); 
      } 
     } 
     return width; 
    } 

    @Override 
    public int drawText(String text, LabelLayout layout) throws OutputException { 
     return 0; 
    } 

    @Override 
    public void endDraw(int width, int height) throws OutputException {} 

    @Override 
    public void paintBackground(int x, int y, int width, int height) {} 

    @Override 
    public void toggleDrawingColor() { 
     toggleDrawingColor = !toggleDrawingColor; 
    } 

} 
+0

它的工作原理。起初,条码已生成,但不会扫描。有两种可能的修复方法:1)将SCALAR更改为1,但条形码很大(并且很难看),或者2)在Adobe设置(或等效)中更改DPI:编辑 - >首选项 - >页面显示 - >分辨率 - 自定义分辨率为300像素/英寸)。我在96. –

+0

我知道这不是评论的目的,但非常感谢你,这对我来说非常完美。 – UpAllNight