GOOGLE ADS

dimanche 17 avril 2022

PdfFileReader.getFields() renvoie {} | Django

J'essaie de lire un formulaire pdf avec django. Le fait est que dans une autre vue de mon views.py j'ai réussi à le faire en utilisant PyPDF2 et sa méthode PdfFileReader.getFields(). Maintenant, le problème est que la lecture ne fonctionne pas correctement : j'ai vérifié avec Adobe Acrobat et le fichier est toujours un formulaire avec des champs, donc je n'ai pas vraiment d'idée de ce qui pourrait être le problème.

Je joins ici la partie pertinente du code :

if request.method == "POST":
form = Form(request.POST, request.FILES) # the form refer to a model called 'New Request'
if form.is_valid():
form.save()
File = request.FILES['File'].name
full_filename = os.path.join(BASE_DIR, 'media/media', File)
f = PdfFileReader(full_filename)
fields = f.getFields()
fdfinfo = dict((k, v.get('/V', '')) for k, v in fields.items())
k = creare_from_pdf2(request, fdfinfo, pk) # this is a custom function
nr = NewRequest.objects.all() #I'm deleting the object uploaded because it won't be useful anymore
nr.delete()
os.remove(full_filename)

Si je l'affiche print(fdfinfo), il affiche réellement {}. Cela conduit bien sûr à une erreur lorsque fdfinfo passe dans la fonction 'create_from_pdf_2'. Je ne sais pas vraiment quel pourrait être le problème, aussi parce que dans une autre vue j'ai fait exactement la même chose et ça marche:

if request.method=='POST':
form = Form(request.POST, request.FILES)
if form.is_valid():
form.save()
uploaded_filename = request.FILES['File'].name
full_filename = os.path.join(BASE_DIR, 'media/media', uploaded_filename)
f = PdfFileReader(full_filename)
fields = f.getFields()
fdfinfo = dict((k, v.get('/V', '')) for k, v in fields.items())
k=create_from_pdf1(request, fdfinfo)
if k==1:
return HttpResponse('<html><body>Something went wrong</html></body>')
nr = NewRequest.objects.all()
nr.delete()
os.remove(full_filename)

Peut-être existe-t-il un moyen d'afficher les erreurs de PdfFileReader?

MISE À JOUR

Le nouveau fichier que j'essaie de lire est d'abord modifié dans le sens où certains champs (MAIS PAS TOUS!) Sont remplis avec PdfFileWriter, et celui rempli est alors défini sur uniquement lisible. Cette opération aurait-elle pu influencer les performances de PdfFileReader? Je joins la vue correspondante

att = MAIN.objects.get(id=pk)
file_path = os.path.join(BASE_DIR, 'nuova_form.pdf')
input_stream = open(file_path, "rb")
pdf_reader = PdfFileReader(input_stream, strict = False)
if "/AcroForm" in pdf_reader.trailer["/Root"]:
pdf_reader.trailer["/Root"]["/AcroForm"].update(
{NameObject("/NeedAppearances"): BooleanObject(True)})
pdf_writer = PdfFileWriter()
set_need_appearances_writer(pdf_writer)
if "/AcroForm" in pdf_writer._root_object:
# Acro form is form field, set needs appearances to fix printing issues
pdf_writer._root_object["/AcroForm"].update(
{NameObject("/NeedAppearances"): BooleanObject(True)})
data_dict1 = { # my text fields
}
data_dict2 = { # my booleancheckbox fields }
for i in range(0,6): #The pdf file has 6 pages
pdf_writer.addPage(pdf_reader.getPage(i))
page = pdf_writer.getPage(i)

# update form fields
pdf_writer.updatePageFormFieldValues(page, data_dict1)
for j in range(0, len(page['/Annots'])):
writer_annot = page['/Annots'][j].getObject()
for field in data_dict1:
if writer_annot.get('/T') == field:
writer_annot.update({
NameObject("/Ff"): NumberObject(1) # make ReadOnly
})
# update checkbox fields
updateCheckboxValues(page, data_dict2)
output_stream = BytesIO()
pdf_writer.write(output_stream)
return output_stream
def updateCheckboxValues(page, fields):
for j in range(0, len(page['/Annots'])):
writer_annot = page['/Annots'][j].getObject()
for field in fields:
if writer_annot.get('/T') == field:
writer_annot.update({
NameObject("/V"): NameObject(fields[field]),
NameObject("/AS"): NameObject(fields[field])
})


Solution du problème

J'ai obtenu des résultats similaires en essayant de lire directement un formulaire PDF en utilisant Python et PyPDF2. Le formulaire PDF avait été créé à l'aide de Libre Writer et consistait en une seule page contenant environ 50 champs de texte. Lorsque j'ai exécuté la méthode getFields() sur l'objet lecteur, j'ai eu le même problème - il renvoyait un objet dict vide.

J'ai pensé qu'il pourrait y avoir une limitation du nombre de champs et j'ai essayé d'en supprimer certains pour les tests, mais j'ai obtenu le même résultat. Ensuite, en le regardant, j'ai remarqué que les noms de champ étaient tous assez longs : txtLabMemberFirstName01, txtLabMemberLastName01, txtPrincipalInvestigatorFirstName, etc.

J'ai raccourci tous les noms de champs (par exemple, "txtLMFN01") et PyPDF2 a recommencé à fonctionner comme prévu.

Aucun commentaire:

Enregistrer un commentaire

Comment utiliseriez-vous .reduce() sur des arguments au lieu d'un tableau ou d'un objet spécifique&nbsp;?

Je veux définir une fonction.flatten qui aplatit plusieurs éléments en un seul tableau. Je sais que ce qui suit n'est pas possible, mais...