[
https://issues.apache.org/jira/browse/PDFBOX-5686?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17768020#comment-17768020
]
Maruan Sahyoun commented on PDFBOX-5686:
----------------------------------------
Please try the sample code below which works for me
{code:java}
PDDocument document = Loader.loadPDF(new
File("/home/msahyoun/Downloads/ZK.pdf"));
PDAcroForm acroform = document.getDocumentCatalog().getAcroForm(null);
PDResources formResources = acroform.getDefaultResources();
PDTrueTypeFont font = (PDTrueTypeFont)
formResources.getFont(COSName.getPDFName("Arial"));
// here is the 'magic' to reuse the font as a new font resource
TrueTypeFont ttFont = font.getTrueTypeFont();
PDFont font2 = PDType0Font.load(document, ttFont, false);
ttFont.close();
// overwrite the preexisiting Arial entry with the new resource
formResources.put(COSName.getPDFName("Arial"), font2);
PDTextField txtField = (PDTextField) acroform.getField("ZP_POJISTENY_OJ");
txtField.setValue("společnost");
document.save("/home/msahyoun/Downloads/ZK-enhanced.pdf");
{code}
The basic idea is that although Arial is being already available in the PDFs
AcroForm resources the fact that it's encoding is set to WinAnsiEncoding limits
to use characters within that altough the embedded font file is also supporting
Czech characters. So what the code does is to read the embedded font file as a
new font and replaces the existing font resource with the new font which is now
using Identity-H (Unicode).
As a result the Czech character can be set.
I'm closing the ticket as this is not a bug but a limitation of the current PDF
form template and a how to question which is better asked on the users mailing
list.. Setting to WinAnsiEncoding and trying to use characters outside of that
will not work and as a result throwing an exception is intended.
So you have to modify the PDF template upfront or on the fly before loading the
XFDF.
> Acroform international (czech) characters can't be written to the textfields
> ----------------------------------------------------------------------------
>
> Key: PDFBOX-5686
> URL: https://issues.apache.org/jira/browse/PDFBOX-5686
> Project: PDFBox
> Issue Type: Bug
> Components: AcroForm
> Affects Versions: 3.0.0 PDFBox
> Environment: Windows 11, JDK 14
> Reporter: Břetislav Černík
> Priority: Major
> Labels: Appearance
> Attachments: ZK.pdf, ZK_BAD.XFDF, ZK_Ok.XFDF
>
>
> I try use the ImportXFDF.java but it does not work for the czech characters
> in the xfdf file.
> The error is
> Exception in thread "main" java.lang.IllegalArgumentException: U+0159 is not
> available in this font's encoding: WinAnsiEncoding
> at
> org.apache.pdfbox.pdmodel.font.PDTrueTypeFont.encode(PDTrueTypeFont.java:404)
> at org.apache.pdfbox.pdmodel.font.PDFont.encode(PDFont.java:337)
> at org.apache.pdfbox.pdmodel.font.PDFont.getStringWidth(PDFont.java:368)
> at
> org.apache.pdfbox.pdmodel.interactive.form.PlainText$Paragraph.getLines(PlainText.java:178)
> at
> org.apache.pdfbox.pdmodel.interactive.form.PlainTextFormatter.format(PlainTextFormatter.java:182)
> at
> org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.insertGeneratedAppearance(AppearanceGeneratorHelper.java:609)
> at
> org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.setAppearanceContent(AppearanceGeneratorHelper.java:443)
> at
> org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.setAppearanceValue(AppearanceGeneratorHelper.java:259)
> at
> org.apache.pdfbox.pdmodel.interactive.form.PDTextField.constructAppearances(PDTextField.java:262)
> at
> org.apache.pdfbox.pdmodel.interactive.form.PDTerminalField.applyChange(PDTerminalField.java:209)
> at
> org.apache.pdfbox.pdmodel.interactive.form.PDTextField.setValue(PDTextField.java:218)
> at formpdf.ImportXFDF.lambda$setFont$0(ImportXFDF.java:194)
> at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
> at formpdf.ImportXFDF.setFont(ImportXFDF.java:178)
> at formpdf.ImportXFDF.importXFDF(ImportXFDF.java:137)
> at Test.TestFormPDF(Test.java:23)
> at Test.main(Test.java:18)
>
> I try to set the TTF Unicode font for every textfields but the same error is
> generated.
> There are test code from modified ImportXFDF. I use the method importXFDF
> package formpdf;
> //import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
> import java.io.BufferedOutputStream;
> import java.io.IOException;
> import java.io.InputStream;
> import java.io.OutputStream;
> import java.io.OutputStreamWriter;
> import java.io.UncheckedIOException;
> import java.io.File;
> import java.util.Iterator;
> import static org.apache.pdfbox.cos.COSName.Off;
> import org.apache.pdfbox.cos.COSName;
> import org.apache.pdfbox.pdmodel.PDDocument;
> import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
> import org.apache.pdfbox.pdmodel.PDResources;
> import org.apache.pdfbox.pdmodel.fdf.FDFDocument;
> import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
> import org.apache.pdfbox.pdmodel.interactive.form.PDCheckBox;
> import org.apache.pdfbox.pdmodel.interactive.form.PDComboBox;
> import org.apache.pdfbox.pdmodel.interactive.form.PDField;
> import org.apache.pdfbox.pdmodel.interactive.form.PDListBox;
> import org.apache.pdfbox.pdmodel.interactive.form.PDRadioButton;
> import org.apache.pdfbox.pdmodel.interactive.form.PDTextField;
> import org.apache.pdfbox.Loader;
> import org.apache.pdfbox.pdmodel.font.PDFont;
> import org.apache.pdfbox.pdmodel.font.PDType0Font;
> import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont;
> import org.apache.pdfbox.pdmodel.font.encoding.Encoding;
> import org.apache.pdfbox.pdmodel.font.encoding.StandardEncoding;
> import org.apache.pdfbox.pdmodel.font.encoding.WinAnsiEncoding;
> import org.apache.pdfbox.pdmodel.font.encoding.GlyphList;
> import org.apache.pdfbox.cos.COSBase;
> import org.apache.pdfbox.cos.COSName;
> import org.apache.fontbox.ttf.TrueTypeFont;
> public class ImportXFDF
> {
> /**
> * @param ac_PDFDocument
> * @param ac_XFDFData
> * @param ac_PDFResult
> * @param ab_clearFields
> * @throws IOException
> */
> public static void importXFDF
> (
> InputStream ac_PDFDocument,
> InputStream ac_XFDFData,
> OutputStream ac_PDFResult,
> boolean ab_clearFields,
> boolean ab_RemoveFields
> ) throws IOException
> {
> PDDocument
> lc_PDDDocument = null;
> String ls_FontName = "ArialMT";
> // MyEncoding
> // lc_Encoding;
> // lc_Encoding = new MyEncoding();
> // lc_Encoding.addChar( 0x0159, "rcaron" );
> try
> {
> lc_PDDDocument = Loader.loadPDF( ac_PDFDocument.readAllBytes() );
> //PDDocument.load( ac_PDFDocument);
>
> }
> catch (IOException ex)
> {
> throw new IOException("Error while reading pdf", ex);
> }
>
>
> FDFDocument fdfDocument = null;
> try
> {
> // fdfDocument = FDFDocument.loadXFDF( ac_XFDFData);
> fdfDocument = Loader.loadXFDF( ac_XFDFData);
> }
> catch (IOException ex)
> {
> throw new IOException("Error while reading xfdf file", ex);
> }
> PDDocumentCatalog docCatalog = lc_PDDDocument.getDocumentCatalog();
> PDAcroForm acroForm = docCatalog.getAcroForm();
> if(acroForm == null){
> throw new IOException("Internal Error with acroform");
> }
> PDResources formResources = acroForm.getDefaultResources();
> // PDTrueTypeFont lc_Arial = (PDTrueTypeFont)
> formResources.getFont(COSName.getPDFName( "Arial" ));
> // TrueTypeFont lc_ArialTTF = lc_Arial.getTrueTypeFont();
> // PDFont lc_ArialNew = PDType0Font.load( lc_PDDDocument,
> lc_ArialTTF, true);
> // lc_ArialTTF.close();
>
> // PDFont lc_Arial = PDTrueTypeFont.load( lc_PDDDocument, new
> File("C:\\Windows\\Fonts\\arial.ttf"),lc_Encoding );
> PDFont lc_Arial = PDType0Font.load( lc_PDDDocument, new
> File("C:\\Windows\\Fonts\\arial.ttf") );
> // lc_Arial.addToSubset( 0x0159 );
> // lc_Arial.subset();
> // PDFont lc_ArialB = PDTrueTypeFont.load( lc_PDDDocument, new
> File("C:\\Windows\\Fonts\\arialbd.ttf"), lc_Encoding );
> // PDFont lc_CourNB = PDTrueTypeFont.load( lc_PDDDocument, new
> File("C:\\Windows\\Fonts\\courbd.ttf"), lc_Encoding );
> // formResources.put( COSName.getPDFName( ls_FontName ), lc_ArialNew
> );
> ls_FontName = formResources.add(lc_Arial).getName();
> System.out.println( ls_FontName );
> // formResources.add(lc_ArialB);
> // formResources.add(lc_CourNB);
> System.out.println( formResources.getFontNames());
> acroForm.setDefaultAppearance( String.format("/%s 0 Tf 0 g",
> ls_FontName ));
> // PDFont lc_font = PDType0Font.load(lc_PDDDocument, new
> File("C://Windows/Fonts/arial.ttf"));
> // formResources.put(COSName.getPDFName("Arial"), lc_font);
> // formResources.add(lc_font);
> // System.out.println( formResources.getFontNames());
> // acroForm.setDefaultResources(formResources);
> // acroForm.setDefaultAppearance("/Arial 0 Tf 0 g");
> // System.out.println( acroForm.getDefaultAppearance());
> acroForm.setCacheFields( true );
> if (ab_clearFields) {
> try
> {
> ClearFileds(acroForm.getFieldIterator());
> }
> catch (UncheckedIOException ex)
> {
> throw new IOException("Error during clearing field forms",
> ex);
> }
> }
> /*
> */
> acroForm.setNeedAppearances( true );
> setFont(acroForm.getFieldIterator(), ls_FontName );
> acroForm.setNeedAppearances( true );
> try
> {
> acroForm.importFDF(fdfDocument);
> }
> catch (IOException ex)
> {
> throw new IOException("Error while importing data", ex);
> }
> acroForm.setNeedAppearances(true);
> if ( ab_RemoveFields )
> {
> acroForm.setNeedAppearances(false);
> try
> {
> acroForm.refreshAppearances();
> }
> catch (IOException e )
> {
> throw new IOException( "Chyba při obnově vzhledu", e );
> }
> System.out.println( "Flatten" );
> acroForm.flatten();
> }
> // konec úpravy aby ukazoval správn? vzhled
> try
> {
> lc_PDDDocument.save(new BufferedOutputStream( ac_PDFResult ));
> }
> catch(IOException ex)
> {
> throw new IOException("Error while saving to pdf", ex);
> }
> }
> private static void setFont(Iterator<PDField> ac_FieldIterator, String
> as_FontName ) throws UncheckedIOException
> {
> ac_FieldIterator.forEachRemaining
> (
> (field) ->
> {
> if (field instanceof PDTextField)
> {
> // System.out.println(((PDTextField)
> field).getDefaultAppearance());
> // ((PDTextField) field).setDefaultAppearance("/F19 0 Tf 0
> g");
> ((PDTextField)field).setDefaultAppearance( String.format("/%s
> 0 Tf 0 g", as_FontName ));
> System.out.println( field.getFullyQualifiedName() + ": " +
> ((PDTextField)field).getDefaultAppearance() + " to " + String.format("/%s 10
> Tf 0 g", as_FontName ) );
> try
> {
> if (field.getFullyQualifiedName()=="PL_NAZEV" )
> {}
> else
> ((PDTextField) field).setValue("\u0159" ); //Příliš žluťoučký
> kůň úpěl ďábelské ódy");
> }
> catch (IOException e)
> {
> throw new UncheckedIOException( e );
> }
> }
> }
> );
> }
> private static void ClearFileds(Iterator<PDField> ac_FieldIterator)
> throws UncheckedIOException
> {
> ac_FieldIterator.forEachRemaining
> (
> (field) ->
> {
> try {
> if (field instanceof PDCheckBox)
> {
> ((PDCheckBox) field).unCheck();
> }
> else if (field instanceof PDComboBox)
> {
> field.setValue(Off.getName());
> }
> else if (field instanceof PDListBox)
> {
> field.setValue(Off.getName());
> }
> else if (field instanceof PDRadioButton)
> {
> field.setValue(Off.getName());
> }
> else if (field instanceof PDTextField)
> {
> // System.out.println(((PDTextField)
> field).getDefaultAppearance());
> // ((PDTextField) field).setDefaultAppearance("/F19 0 Tf 0
> g");
> field.setValue("");
> }
> }
> catch (IOException ex )
> {
> throw new UncheckedIOException(ex);
> }
> }
> );
> }
> /**
> * @param ac_PDFDocument
> * @param ac_XFDFData
> * @throws IOException
> */
> public static void exportXFDF(InputStream ac_PDFDocument, OutputStream
> ac_XFDFData )
> throws IOException
> {
> OutputStreamWriter outputStreamWriter = new
> OutputStreamWriter(ac_XFDFData);
> PDDocumentCatalog lc_pdDocumentDocumentCatalog;
> PDDocument lc_pdDocument = null;
> PDAcroForm lc_acroForm;
> try {
> // lc_pdDocument = PDDocument.load(ac_PDFDocument);
> lc_pdDocument = Loader.loadPDF( ac_PDFDocument.readAllBytes());
> }
> catch (IOException ex)
> {
> throw new IOException("Error while reading pdf", ex);
> }
> lc_pdDocumentDocumentCatalog = lc_pdDocument.getDocumentCatalog();
> lc_acroForm = lc_pdDocumentDocumentCatalog.getAcroForm();
> FDFDocument lc_fdfDocument = null;
> try {
> lc_fdfDocument = lc_acroForm.exportFDF();
> }catch(IOException ex){
> throw new IOException("Error while exporting fdf", ex);
> }
> try{
> lc_fdfDocument.saveXFDF(outputStreamWriter);
> } catch (IOException ex){
> throw new IOException("Error during saving XFDF",ex);
> }
> }
> }
>
> The acroForm.setNeedAppearances( true ) is not usable for the final output.
> It is not suported in the some viewers I.e. apple tablets
> Best regards
> Břetislav Černík
> [email protected]
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]