Skip to content

Commit

Permalink
[US-557] Create example code for form fields with text colors (#256)
Browse files Browse the repository at this point in the history
* added example for form fields with text colors

* update unipdf version to 3.61

* fix go.sum

* updated README.md and producer version in pdf_form_with_text_color.go code.
  • Loading branch information
kellemNegasi authored Jul 30, 2024
1 parent 227d174 commit 08cf488
Show file tree
Hide file tree
Showing 8 changed files with 337 additions and 9 deletions.
2 changes: 2 additions & 0 deletions forms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ forms.
- [pdf_form_get_field_data.go](pdf_form_get_field_data.go) gets field data for a single field by field name.
- [pdf_form_list_fields.go](pdf_form_list_fields.go) lists form fields in a PDF.
- [pdf_form_fields_rotations.go](pdf_form_fields_rotations.go) form fields with customized rotation in a PDF.
- [pdf_form_with_text_color.go](pdf_form_with_text_color.go) form fields with custom text color.
- [pdf_fill_and_flatten_with_apearance.go](pdf_fill_and_flatten_with_apearance.go) flatten or fill PDF forms with custom appearance including text color.

## Use cases

Expand Down
Binary file added forms/form_field_with_colored_text_fields.pdf
Binary file not shown.
121 changes: 121 additions & 0 deletions forms/pdf_fill_and_flatten_with_apearance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Fill PDF form JSON input data and flatten it with a customized appearance to output PDF.
*
* Run as: go run pdf_fill_and_flatten_with_apearance.go.
*/

package main

import (
"fmt"
"os"

"github.com/unidoc/unipdf/v3/annotator"
"github.com/unidoc/unipdf/v3/common/license"
"github.com/unidoc/unipdf/v3/fjson"
"github.com/unidoc/unipdf/v3/model"
)

func init() {
// Make sure to load your metered License API key prior to using the library.
// If you need a key, you can sign up and create a free one at https://cloud.unidoc.io
err := license.SetMeteredKey(os.Getenv(`UNIDOC_LICENSE_API_KEY`))
if err != nil {
panic(err)
}
}

func main() {
inputPath := "./sample_form.pdf"
jsonDataPath := "./sample_form.json"
outputPath := "./sample_form_output.pdf"

// Output path not specified: Export list of fields and data as JSON format.
if len(outputPath) == 0 {
fdata, err := fjson.LoadFromPDFFile(inputPath)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
if fdata == nil {
fmt.Printf("No data\n")
return
}
fjson, err := fdata.JSON()
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
fmt.Printf("%s\n", fjson)
return
}

err := fillFieldsWithAppearance(inputPath, jsonDataPath, outputPath)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}

fmt.Printf("Success, output written to %s\n", outputPath)
}

// fillFieldsWithAppearance loads field data from `jsonPath` and to fills the data to form fields in a PDF data provided via `inputPath` and outputs
// as a flattened PDF in `outputPath`. Customized field appearance can be given either during filling or during flattening via the
// `annotator.AppearanceStyle` object.
func fillFieldsWithAppearance(inputPath, jsonPath, outputPath string) error {
fdata, err := fjson.LoadFromJSONFile(jsonPath)
if err != nil {
return err
}

f, err := os.Open(inputPath)
if err != nil {
return err
}
defer f.Close()

pdfReader, err := model.NewPdfReader(f)
if err != nil {
return err
}

fieldAppearance := annotator.FieldAppearance{OnlyIfMissing: true, RegenerateTextFields: true}

// specify a full set of appearance styles
fieldAppearance.SetStyle(annotator.AppearanceStyle{
AutoFontSizeFraction: 0.70,
FillColor: model.NewPdfColorDeviceRGB(1, 1, 1),
BorderColor: model.NewPdfColorDeviceRGB(0, 0, 0),
BorderSize: 2.0,
AllowMK: false,
TextColor: model.NewPdfColorDeviceRGB(0.5, 0.8, 0.8),
})

// Populate the form data.
// pdfReader.AcroForm.FillWithAppearance(fdata, fieldAppearance) // uncomment this line to fill with appearance
pdfReader.AcroForm.Fill(fdata)

// Flatten form. with field appearance
err = pdfReader.FlattenFields(true, fieldAppearance)
if err != nil {
return err
}

// Generate a PdfWriter instance from existing PdfReader.
pdfWriter, err := pdfReader.ToWriter(nil)
if err != nil {
return err
}

// Write to file.
err = pdfWriter.WriteToFile(outputPath)
return err
}

func getFont(path string) (*model.PdfFont, error) {
font, err := model.NewCompositePdfFontFromTTFFile(path)
if err != nil {
return nil, err
}
return font, nil
}
147 changes: 147 additions & 0 deletions forms/pdf_form_with_text_color.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* Create a new form with customized text field colors.
* The example shows how to create a form that has customized text field colors.
* The form has submit and reset buttons.
* Run as: go pdf_form_with_text_color.go
*/
package main

import (
"fmt"
"os"
"path/filepath"

"github.com/unidoc/unipdf/v3/annotator"
"github.com/unidoc/unipdf/v3/common/license"
"github.com/unidoc/unipdf/v3/contentstream/draw"
"github.com/unidoc/unipdf/v3/core"
"github.com/unidoc/unipdf/v3/creator"
"github.com/unidoc/unipdf/v3/model"
)

func init() {
// Make sure to load your metered License API key prior to using the library.
// If you need a key, you can sign up and create a free one at https://cloud.unidoc.io
err := license.SetMeteredKey(os.Getenv(`UNIDOC_LICENSE_API_KEY`))
if err != nil {
panic(err)
}
}

func main() {
textFieldsDef := []struct {
Label string
Name string
SampleInput string
Rect []float64
}{
{Label: "Full Name", Name: "full_name", SampleInput: "Enter Full Name", Rect: []float64{123.97, 619.02, 343.99, 633.6}},
{Label: "Address 1", Name: "address_line_1", SampleInput: "Enter Address 1", Rect: []float64{123.97, 596.82, 343.99, 611.4}},
{Label: "Address 2", Name: "address_line_2", SampleInput: "Enter Address 2", Rect: []float64{123.97, 574.28, 343.99, 588.86}},
}

c := creator.New()
page := c.NewPage()

_, pageHeight, err := page.Size()
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}

form := model.NewPdfAcroForm()
fields := core.MakeArray()

for _, fdef := range textFieldsDef {
opt := annotator.TextFieldOptions{
TextColor: "#0000FF", // Set text color to Blue.
Value: fdef.SampleInput,
}
textf, err := annotator.NewTextField(page, fdef.Name, fdef.Rect, opt)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}

*form.Fields = append(*form.Fields, textf.PdfField)
page.AddAnnotation(textf.Annotations[0].PdfAnnotation)

y := pageHeight - fdef.Rect[1]

p := c.NewParagraph(fdef.Label)
p.SetPos(fdef.Rect[0]-80, y-10)
err = c.Draw(p)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}

line := c.NewLine(fdef.Rect[0], y, fdef.Rect[2], y)
err = c.Draw(line)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}

fields.Append(textf.ToPdfObject())
}

// Add Submit button
optSubmit := annotator.FormSubmitActionOptions{
Url: "https://unidoc.io",
Rectangle: draw.Rectangle{
X: 400.0,
Y: 400.0,
Width: 50.0,
Height: 20.0,
FillColor: model.NewPdfColorDeviceRGB(0.0, 1.0, 0.0),
},
Label: "Submit",
LabelColor: model.NewPdfColorDeviceRGB(1.0, 0.0, 0.0),
}

btnSubmitField, err := annotator.NewFormSubmitButtonField(page, optSubmit)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}

*form.Fields = append(*form.Fields, btnSubmitField.PdfField)
page.AddAnnotation(btnSubmitField.Annotations[0].PdfAnnotation)

// Add Reset button
optReset := annotator.FormResetActionOptions{
Rectangle: draw.Rectangle{
X: 100.0,
Y: 400.0,
Width: 50.0,
Height: 20.0,
FillColor: model.NewPdfColorDeviceGray(0.5),
},
Label: "Reset",
LabelColor: model.NewPdfColorDeviceGray(1.0),
Fields: fields,
}

btnResetField, err := annotator.NewFormResetButtonField(page, optReset)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}

// Add widget to existing form.
*form.Fields = append(*form.Fields, btnResetField.PdfField)
page.AddAnnotation(btnResetField.Annotations[0].PdfAnnotation)

c.SetForms(form)

model.SetPdfProducer(`UniDoc v3.61.0 (Unlicensed) - http://unidoc.io`)
defer model.SetPdfProducer("")

outPath := filepath.Join(".", "form_field_with_colored_text_fields.pdf")
err = c.WriteToFile(outPath)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
}
58 changes: 58 additions & 0 deletions forms/sample_form.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
[
{
"name": "formID",
"value": "202286033286049"
},
{
"name": "pdf_submission_new",
"value": "1"
},
{
"name": "simple_spc",
"value": "202286033286049-202286033286049"
},
{
"name": "adobeWarning",
"value": "In order to submit this form, you should open it with Adobe Acrobat Reader."
},
{
"name": "name3[first]",
"value": "John"
},
{
"name": "name3[last]",
"value": "Doe"
},
{
"name": "email4",
"value": "alpha@omega.com"
},
{
"name": "address5[addr_line1]",
"value": "sample address line 1"
},
{
"name": "address5[addr_line2]",
"value": "sample address line 2"
},
{
"name": "address5[city]",
"value": "sample address"
},
{
"name": "address5[state]",
"value": "sample state"
},
{
"name": "address5[postal]",
"value": "3538148"
},
{
"name": "fakeSubmitButton",
"value": "Submit"
},
{
"name": "submitButton",
"value": ""
}
]
Binary file added forms/sample_form_output.pdf
Binary file not shown.
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ require (
github.com/unidoc/globalsign-dss v0.0.0-20220330092912-b69d85b63736
github.com/unidoc/pkcs7 v0.2.0
github.com/unidoc/unichart v0.3.0
github.com/unidoc/unipdf/v3 v3.59.0
github.com/unidoc/unipdf/v3 v3.61.0
github.com/wcharczuk/go-chart/v2 v2.1.0
golang.org/x/crypto v0.22.0
golang.org/x/image v0.15.0
golang.org/x/text v0.14.0
golang.org/x/image v0.18.0
golang.org/x/text v0.16.0
google.golang.org/api v0.114.0
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1
google.golang.org/protobuf v1.30.0
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ github.com/unidoc/timestamp v0.0.0-20200412005513-91597fd3793a h1:RLtvUhe4DsUDl6
github.com/unidoc/timestamp v0.0.0-20200412005513-91597fd3793a/go.mod h1:j+qMWZVpZFTvDey3zxUkSgPJZEX33tDgU/QIA0IzCUw=
github.com/unidoc/unichart v0.3.0 h1:VX1j5yzhjrR3f2flC03Yat6/WF3h7Z+DLEvJLoTGhoc=
github.com/unidoc/unichart v0.3.0/go.mod h1:8JnLNKSOl8yQt1jXewNgYFHhFm5M6/ZiaydncFDpakA=
github.com/unidoc/unipdf/v3 v3.59.0 h1:Kgo1+s/KYQyz7YLvBTrH9vu0E7Q0hPklm8KmVBGPACQ=
github.com/unidoc/unipdf/v3 v3.59.0/go.mod h1:HEGsUAyg0cI46ofB2D4b6FzBXzVM2P1mHvQ5R+HxONs=
github.com/unidoc/unipdf/v3 v3.61.0 h1:oyp0jnY1JxTcrNSpC7xTBw5aWg35IqLanwI2klqjvbw=
github.com/unidoc/unipdf/v3 v3.61.0/go.mod h1:0OIzSHHno23Y8WzaK+852abK8d3AxUZ1GQkMqpyCzu8=
github.com/unidoc/unitype v0.4.0 h1:/TMZ3wgwfWWX64mU5x2O9no9UmoBqYCB089LYYqHyQQ=
github.com/unidoc/unitype v0.4.0/go.mod h1:HV5zuUeqMKA4QgYQq3KDlJY/P96XF90BQB+6czK6LVA=
github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I=
Expand All @@ -145,8 +145,8 @@ golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
Expand Down Expand Up @@ -184,8 +184,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
Expand Down

0 comments on commit 08cf488

Please sign in to comment.