tpisto / pdf-fill-form

Fill PDF forms and return either filled PDF or PDF created from rendered page images.
MIT License
227 stars 48 forks source link

input type combo boxes not supplying selected value #94

Open IrishAdo opened 4 years ago

IrishAdo commented 4 years ago

OK so I used this online pdf example to produce several test files

http://foersom.com/net/HowTo/data/OoPdfFormExample.pdf

quite simple you fill it in and save as and you have an example file to play with.

This is my test code

var pdfFillForm = require('pdf-fill-form');
var tests = require('./test-definition');

tests.testFiles.forEach((test,index) =>{
    pdfFillForm.read('./'+test.filename)
    .then(function(result) {
        console.log(' -- TEST '+index +' '+ test.description);
        console.log('pdf results');
        console.log(result);
    }, function(err) {
        console.log(err);
    });
})

my test definition file just gives a list of test pdfs and a description of what I'm expecting here is the result for that pdf with everything filled in (NOTE if you open the saved PDF all fields are filled in correctly but the PDF forms can not get the values of the combo boxes)

Extract a document with fields filled in
[
  {
    name: 'Given Name Text Box',
    page: 0,
    value: 'Alfred',
    id: 65536,
    type: 'text'
  },
  {
    name: 'Family Name Text Box',
    page: 0,
    value: 'Montique',
    id: 65537,
    type: 'text'
  },
  {
    name: 'Address 1 Text Box',
    page: 0,
    value: 'Venice Beach',
    id: 65538,
    type: 'text'
  },
  {
    name: 'House nr Text Box',
    page: 0,
    value: '10290',
    id: 65539,
    type: 'text'
  },
  {
    name: 'Address 2 Text Box',
    page: 0,
    value: 'A sand dune',
    id: 65540,
    type: 'text'
  },
  {
    name: 'Postcode Text Box',
    page: 0,
    value: '12345',
    id: 65541,
    type: 'text'
  },
  {
    name: 'City Text Box',
    page: 0,
    value: 'Venice',
    id: 65542,
    type: 'text'
  },
  {
    name: 'Country Combo Box',
    page: 0,
    value: undefined,
    id: 65543,
    choices: [
      'Austria',        'Belgium',
      'Britain',        'Bulgaria',
      'Croatia',        'Cyprus',
      'Czech-Republic', 'Denmark',
      'Estonia',        'Finland',
      'France',         'Germany',
      'Greece',         'Hungary',
      'Ireland',        'Italy',
      'Latvia',         'Lithuania',
      'Luxembourg',     'Malta',
      'Netherlands',    'Poland',
      'Portugal',       'Romania',
      'Slovakia',       'Slovenia',
      'Spain',          'Sweden'
    ],
    type: 'combobox'
  },
  {
    name: 'Gender List Box',
    page: 0,
    value: undefined,
    id: 65544,
    choices: [ 'Man', 'Woman' ],
    type: 'combobox'
  },
  {
    name: 'Height Formatted Field',
    page: 0,
    value: '150',
    id: 65545,
    type: 'text'
  },
  {
    name: 'Driving License Check Box',
    page: 0,
    value: true,
    id: 65546,
    type: 'checkbox'
  },
  {
    name: 'Language 1 Check Box',
    page: 0,
    value: false,
    id: 65547,
    type: 'checkbox'
  },
  {
    name: 'Language 2 Check Box',
    page: 0,
    value: true,
    id: 65548,
    type: 'checkbox'
  },
  {
    name: 'Language 3 Check Box',
    page: 0,
    value: false,
    id: 65549,
    type: 'checkbox'
  },
  {
    name: 'Language 4 Check Box',
    page: 0,
    value: false,
    id: 65550,
    type: 'checkbox'
  },
  {
    name: 'Language 5 Check Box',
    page: 0,
    value: true,
    id: 65551,
    type: 'checkbox'
  },
  {
    name: 'Favourite Colour List Box',
    page: 0,
    value: undefined,
    id: 65552,
    choices: [
      'Black',  'Brown',
      'Red',    'Orange',
      'Yellow', 'Green',
      'Blue',   'Violet',
      'Grey',   'White'
    ],
    type: 'combobox'
  }
]
IrishAdo commented 4 years ago

I have tested the write a pdf function and it is able to set the combo boxes correctly


var pdfFillForm = require('pdf-fill-form');
var fs = require('fs');

var sourceFilename = './write-pdf.pdf';
var targetFilename = './write-pdf-1.pdf';
var fields = {
    'Given Name Text Box': 'Alfred',
    'Family Name Text Box': 'Montique',
    'Address 1 Text Box': 'Venice Beach',
    'House nr Text Box': '10290',
    'Address 2 Text Box': 'A sand dune',
    'Postcode Text Box': '12345',
    'City Text Box': 'Venice',
    'Country Combo Box': 'Germany',
    'Gender List Box': 'Woman',
    'Height Formatted Field': '150',
    'Driving License Check Box': true,
    'Language 1 Check Box': false,
    'Language 2 Check Box': true,
    'Language 3 Check Box': false,
    'Language 4 Check Box': true,
    'Language 5 Check Box': false,
    'Favourite Colour List Box': 'Orange'
};
pdfFillForm.write(
    sourceFilename, 
    fields, 
    { "save": "pdf", 'cores': 4, 'scale': 0.2, 'antialias': true } 
)
.then(function(result) {
    fs.writeFile(targetFilename, result, function(err) {
        if(err) {
            return console.log(err);
        }
        console.log("The file was saved!");
    }); 
}, function(err) {
    console.log(err);
});```
IrishAdo commented 4 years ago

I think that section FormChoice on line 488 of NodePoppler.cc is missing a set value similar to the other types.

like line 283

Nan::Set(obj, Nan::New<String>("value").ToLocalChecked(), Nan::New<String>(((Poppler::FormFieldText *)field)->text().toStdString()).ToLocalChecked());

Sorry I don't know C to be any more help.

IrishAdo commented 4 years ago

Line 367 is were the setting of the value is specified.

if (field->type() == Poppler::FormField::FormChoice) {
          Poppler::FormFieldChoice *choiceField = (Poppler::FormFieldChoice *) field;
          if (choiceField->isEditable()) {
            choiceField->setEditChoice(QString::fromUtf8(params.fields.at(fieldName).c_str()));
          }
          else {
            QStringList possibleChoices = choiceField->choices();
            QString proposedChoice = QString::fromUtf8(params.fields.at(fieldName).c_str());
            int index = possibleChoices.indexOf(proposedChoice);
            if (index >= 0) {
              QList<int> choiceList;
              choiceList << index;
              choiceField->setCurrentChoices(choiceList);
            }
          }
        }