【问题标题】:What to use to generate pdf documents that will incorporate dynamically generated barcodes (Java)?使用什么来生成包含动态生成的条形码 (Java) 的 pdf 文档?
【发布时间】:2011-10-01 10:42:19
【问题描述】:

我的要求要求生成包含任意文本和条形码的 pdf 文档。我有相关的question 解决pdf生成部分,但在这里我想知道如何在Java中将条形码合并到pdf中。

到目前为止,我已经找到了关于barcode4j 如何使用 Apache FOP 的清晰解释:Instructions for the Apache FOP extension

但看起来 XSL-FO 不是我要求的主要选择,因为我更喜欢使用 pdf 表单(使用 iText 或 PDFBox 或类似的)。同样,这还不是最终结果。

您在 pdf 中使用图像或字体作为条形码吗?除了 pdf API 之外,我还应该期待哪些依赖项(字体、库)?

【问题讨论】:

    标签: java pdf pdf-generation barcode


    【解决方案1】:

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

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

    【讨论】:

    • 但这不是免费的:它需要 itext,在我的情况下需要商业许可。
    • 它是 GPL3。它不需要商业许可证,除非您需要身份证明。
    【解决方案2】:

    如果您准备将 PDF 生成要求放宽到使用非 Java 工具,您可能会发现以下内容很有用:

    1. 使用带有条形码占位符的 HTML/CSS/JS 布局您的页面模板。
    2. 使用 Barcode4J 到 output SVG,然后将其放入模板中。
    3. 使用wkhtmltopdf 命令行工具呈现页面。 wkhtmltopdf 在底层使用 WebKit,因此您可以使用 HTML/CSS 很好地控制 PDF 布局。

    【讨论】:

      【解决方案3】:

      为了在 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

      【讨论】:

        【解决方案4】:

        我成功地使用 PDFBox 和 Barbecue 将条形码添加到 PDF。 Barbecue 提供了输出接口来自己绘制条形码。我以这样一种方式实现了这个接口: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;
            }
        
        }
        

        【讨论】:

        • 它有效。起初,条码已生成,但无法扫描。有 2 种可能的修复方法:1)将 SCALAR 更改为 1,但条形码非常大(而且很难看),或者 2)在 Adob​​e 设置(或同等设置)中更改 DPI:编辑 -> 首选项 -> 页面显示 -> 分辨率 ->自定义分辨率为 300 像素/英寸)。我的是 96 岁。
        • 我知道这不是 cmets 的目的,但非常感谢您,这对我来说非常有效。
        猜你喜欢
        • 1970-01-01
        • 2011-01-24
        • 2021-10-27
        • 2014-03-09
        • 1970-01-01
        • 2019-04-16
        • 2017-04-22
        • 1970-01-01
        • 2012-07-12
        相关资源
        最近更新 更多