Пакетное создание штрих-кодов с помощью reportlab

Вчера я задал вопрос, возможно, слишком общий.

Сегодня я реализовал свои идеи, пытаясь реализовать решение.

Используя ReportLab, pdfquery и PyPDF2, я пытаюсь автоматизировать процесс генерации штрих-кодов на сотнях страниц документа 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()

А вот и письма-test.pdf

7
0
685
2

Ответы 2

Причина, по которой ваш штрих-код не меняется, заключается в том, что вы указали слишком длинное целое число в eanbc.Ean8BarcodeWidget.

Согласно стандарту EAN штрих-коды EAN-8 состоят из 8 цифр (7 цифр + контрольная цифра).

Решение:

Если вы измените barcode_value с 12345670 на 1234560 и запустите свой скрипт, вы увидите, что значение штрих-кода увеличивается по вашему желанию, а контрольная цифра добавляется как восьмое число.

Имея эту информацию под рукой, вы должны использовать только 7 цифр для кодирования информации в штрих-коде.

как указал Камил Ники, Ean8BarcodeWidget, ограничивающий количество эффективных цифр до 7:

class Ean8BarcodeWidget(Ean13BarcodeWidget):
    _digits=7
...
self.value=max(self._digits-len(value),0)*'0'+value[:self._digits]

вы можете изменить свою схему кодирования или использовать штрих-код EAN 13 с Ean13BarcodeWidget, который имеет 12 используемых цифр.

Другие вопросы по теме