Hopding / pdf-lib

Create and modify PDF documents in any JavaScript environment
https://pdf-lib.js.org
MIT License
6.6k stars 635 forks source link

.setText() on a form field keeps font-size but overwrites pre-set font and font-color #1597

Open killkoc opened 5 months ago

killkoc commented 5 months ago

What were you trying to do?

I created a form PDF with several form fields. I then set the text for each form field in front-end java script. This works fine, but the preset font and font color are overwritten when set a new text while font size seems to remain correct

How did you attempt to do it?

const response = await fetch('//myPath'); const existingPdfBytes = await response.arrayBuffer(); const pdfDoc = await PDFLib.PDFDocument.load(existingPdfBytes); const pdfForm = pdfDoc.getForm(); pdfForm.getTextField('kid-first').setText(kidFirstName);

What actually happened?

text is changed correctly font size remains pre-set size for the form field font and font color are overwritten default font and black

What did you expect to happen?

text is changed correctly form field's pre-set font, font-size and font-color remain unchanged

How can we reproduce the issue?

Thanks

Version

https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.js

What environment are you running pdf-lib in?

Browser

Checklist

Additional Notes

No response

AndyHryshchenko commented 4 months ago

I was having an issue with it myself, but then reading the PDFTextField.setText specification revealed this:

This method will mark this text field as dirty, causing its appearance streams to be updated when either PDFDocument.save or PDFForm.updateFieldAppearances is called. The updated streams will display the text this field contains inside the widgets of this text field.

IMPORTANT: The default font used to update appearance streams is StandardFonts.Helvetica. Note that this is a WinAnsi font. This means that encoding errors will be thrown if this field contains text outside the WinAnsi character set (the latin alphabet).

Meaning this behaviour is intended. I was able to work my way around this by explicitly updating the form back to the font I needed (luckily it was one of the standard fonts) using PDFForm.updateFieldAppearances:

const courier = await pdfDoc.embedFont(StandardFonts.Courier) const form = pdfDoc.getForm() form.updateFieldAppearances(courier)

I had to do this after I edited my form's fields, right before saving the doc.