benoitkugler / pdf

Golang high level PDF model
MIT License
22 stars 3 forks source link

AppearanceKeys are empty in some checkboxes #11

Closed Chroq closed 4 months ago

Chroq commented 4 months ago

Hi Benoit,

It's me again :) I've almost filled all the CERFA "avis d'arrêt de travail" forms, but I'm still having an issue with some checkboxes.

Before explaining further, I need to mention that this problem only affects certain types of checkboxes. Most of them work flawlessly.

When I target a field and try to get its appearance keys, they are empty:

appearanceKeys := originalFields[key].Field.AppearanceKeys()

You can see this issue with the "INI" field in the attached file.

If you have any ideas, I'm interested. I will also try to check your library and submit a PR.

Thank you!

CERFA_SL.pdf

NB: I've tried using both "INI" and "INI." (since both names exist), but neither made a difference.

benoitkugler commented 4 months ago

Hi Christophe,

This PDF file definitively makes strange choices regarding the AcroForm. In this case, the fields under the "INI" parent actually have empty names. I had not expected such behavior : to fix the issue, I now also use the index in the parent slice to identify a field. More precisely, a field with no name uses its (0-based) index as replacement.

In your case, for the "INI" field, you are then actually looking at "INI.4" and "INI.5". Could you try that using b3aaaf6 ?

Chroq commented 4 months ago

Hi Benoit,

Thank you for the feedback and library improvement!

Yes, I noticed that too :) and it's an official document from the French administration... I hope it doesn't cause too much trouble for your library.

I've tried with the b3aaf6 commit, but I still don't get any keys. Is there something wrong with this snippet?


func (f Filler) Fill(values map[string]any) error {
    originalFields := f.Templater.Document.Catalog.AcroForm.Flatten()
    fields := make([]formfill.FDFField, 0, len(values))
    for key, value := range values {
        f := formfill.Values{}
        switch as := value.(type) {
        case string:
            f.V = formfill.FDFText(as)
        case []string:
            f.V = formfill.FDFChoices(as)
        case time.Time:
            f.V = formfill.FDFText(as.Format(DefaultFrenchFormatDate))
        case bool:
            if !as {
                continue
            }

            var appearanceKeys []model.ObjName
            if field, ok := originalFields[key]; ok {
                appearanceKeys = field.Field.AppearanceKeys()
            }
            if len(appearanceKeys) == 0 {
                continue
            }
            f.V = formfill.FDFName(appearanceKeys[len(appearanceKeys)-1])
        default:
            return referrors.NewInternal(context.TODO(), "invalid type for value")
        }

        fields = append(fields, formfill.FDFField{
            Values: f,
            T:      key,
        })
    }

    return formfill.FillForm(&f.Templater.Document, formfill.FDFDict{
        Fields: fields,
    }, false)
}

Thank you!

Chroq commented 4 months ago

I succeed to check "INI" checkboxes (INI.1/INI.2/INI.4) so I think it works for me !

I close the issue, you did (again) some great job ! Thank you !