使用ReportLab批量生成条形码

7

昨天,我提出了一个可能过于宽泛的问题。

今天,我尝试着实施解决方案,以便落实我的想法。

使用 ReportLabpdfqueryPyPDF2,我正在尝试自动化在 PDF 文档的数百个页面上生成条形码的过程。

每个页面都需要有一个条形码。然而,如果页面右上角有一个字母(从 'A' 到 'E'),那么它需要使用与前一页相同的条形码。带有右上角字母的文件是具有类似信息的重复表格。

如果没有字母出现,则应在该页面上使用唯一的条形码号码(递增一即可)。

我的代码似乎可以工作,但我遇到了两个问题:

  1. 条形码会微微移动(小问题)。
  2. 条形码的值不会改变(重大问题)。所有页面上只设置了第一个条形码号码。

我似乎无法确定值为什么不会改变。有人有线索吗?

代码在这里:

import pdfquery
import os
from io import BytesIO
from PyPDF2 import PdfFileWriter, PdfFileReader
from reportlab.graphics.barcode import eanbc
from reportlab.graphics.shapes import Drawing 
from reportlab.lib.pagesizes import letter
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas
from reportlab.graphics import renderPDF

pdf = pdfquery.PDFQuery("letters-test.pdf")

total_pages = pdf.doc.catalog['Pages'].resolve()['Count']
print("Total pages", total_pages)

barcode_value = 12345670

output = PdfFileWriter()

for i in range(0, total_pages):
    pdf.load(i) # Load page i into memory
    duplicate_letter = pdf.pq('LTTextLineHorizontal:in_bbox("432,720,612,820")').text()

    if duplicate_letter != '':
        print("Page " + str(i+1) + " letter " + str(duplicate_letter))
        print(barcode_value)
        packet = BytesIO()
        c = canvas.Canvas(packet, pagesize=letter)

        # draw the eanbc8 code
        barcode_eanbc8 = eanbc.Ean8BarcodeWidget(str(barcode_value))
        bounds = barcode_eanbc8.getBounds()
        width = bounds[2] - bounds[0]
        height = bounds[3] - bounds[1]
        d = Drawing(50, 10)
        d.add(barcode_eanbc8)
        renderPDF.draw(d, c, 400, 700)
        c.save()

        packet.seek(0)

        new_pdf = PdfFileReader(packet)

        # read existing PDF
        existing_pdf = PdfFileReader(open("letters-test.pdf", "rb"))

        # add the "watermark" (which is the new pdf) on the existing page
        page = existing_pdf.getPage(i)
        page.mergePage(new_pdf.getPage(0))
        output.addPage(page)

    else:
        # increment barcode value
        barcode_value += 1
        print("Page " + str(i+1) + " isn't a duplicate.")
        print(barcode_value)
        packet = BytesIO()
        c = canvas.Canvas(packet, pagesize=letter)

        # draw the eanbc8 code
        barcode_eanbc8 = eanbc.Ean8BarcodeWidget(str(barcode_value))
        bounds = barcode_eanbc8.getBounds()
        width = bounds[2] - bounds[0]
        height = bounds[3] - bounds[1]
        d = Drawing(50, 10)
        d.add(barcode_eanbc8)
        renderPDF.draw(d, c, 420, 710)
        c.save()

        packet.seek(0)

        new_pdf = PdfFileReader(packet)

        # read existing PDF
        existing_pdf = PdfFileReader(open("letters-test.pdf", "rb"))

        # add the "watermark" (which is the new pdf) on the existing page

        page = existing_pdf.getPage(i)
        page.mergePage(new_pdf.getPage(0))
        output.addPage(page)

     # Clear page i from memory and re load.
     # pdf = pdfquery.PDFQuery("letters-test.pdf")


outputStream = open("newpdf.pdf", "wb")
output.write(outputStream)
outputStream.close()

这里是 letters-test.pdf

2个回答

3
正如Kamil Nicki的回答所指出的那样,Ean8BarcodeWidget将有效数字限制为7个:
class Ean8BarcodeWidget(Ean13BarcodeWidget):
    _digits=7
...
self.value=max(self._digits-len(value),0)*'0'+value[:self._digits]

您可以更改编码方案或使用带有Ean13BarcodeWidget的EAN 13条形码,可用12个数字。


2
你的条形码未改变的原因是你在eanbc.Ean8BarcodeWidget中提供了过长的整数。

根据EAN标准,EAN-8条形码长度为8位数字(7位数字+1位校验数字)。
解决方案: 如果你将barcode_value12345670更改为1234560并运行脚本,你会发现条形码值按照你想要的方式增加,并且校验数字附加为第八个数字。
有了这些信息,你应该只使用7位数字来编码条形码中的信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接