Skip to main content
Skip table of contents

Underline a form field value

This example was written in answer to the question Click How to underline a portion of text in a text field?


fillwithunderline

FillWithUnderline Java

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.acroforms;

import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfFormCreator;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Text;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.StringReader;

public class FillWithUnderline {
    public static final String DEST = "./target/sandbox/acroforms/fill_with_underline.pdf";

    public static final String SRC = "./src/main/resources/pdfs/form.pdf";

    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();

        new FillWithUnderline().manipulatePdf(DEST);
    }

    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
        Document doc = new Document(pdfDoc);
        PdfAcroForm form = PdfFormCreator.getAcroForm(pdfDoc, true);

        // If no fields have been explicitly included, then all fields are flattened.
        // Otherwise only the included fields are flattened.
        form.flattenFields();

        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        InputSource is = new InputSource(new StringReader("<root><div>Bruno <u>Lowagie</u></div></root>"));
        Rectangle pos = form.getField("Name").getWidgets().get(0).getRectangle().toRectangle();

        // Custom handler gets position of the form field
        // to fill in the document with the parsed content.
        parser.parse(is, new CustomHandler(doc, pos));

        pdfDoc.close();
    }


    private static class CustomHandler extends DefaultHandler {
        protected Document document;
        protected Rectangle position;
        protected Paragraph paragraph;

        // If isUnderlined flag is true, then parsed text should be underlined.
        protected boolean isUnderlined;

        public CustomHandler(Document document, Rectangle position) {
            this.document = document;
            this.position = position;
            this.paragraph = new Paragraph();
            this.isUnderlined = false;
        }

        /**
         * This method implies that if the handler encounters opening tag <u>,
         * then it sets isUnderlined flag to true.
         */
        public void startElement(String uri, String localName, String qName, Attributes attributes) {
            if ("u".equals(qName)) {
                isUnderlined = true;
            }
        }

        /**
         * This method implies how to handle encountered closing tags </div> and </u>:
         * if </div>, then add the parsed text to the document;
         * if </u>, then set isUnderlined flag to false
         */
        public void endElement(String uri, String localName, String qName) {
            if ("div".equals(qName)) {
                document.add(paragraph.setFixedPosition(position.getLeft(), position.getBottom(), position.getWidth()));

                // Set the position of the next form field.
                position.moveDown(22);
                paragraph = new Paragraph();
            } else if ("u".equals(qName)) {
                isUnderlined = false;
            }
        }

        /**
         * Creates a {@link Text} from the passed parameters and wraps it if not empty with a paragraph.
         */
        public void characters(char[] ch, int start, int length) {
            Text text = new Text(strip(new StringBuffer().append(ch, start, length)));
            if (isUnderlined) {
                text.setUnderline();
            }

            if (0 != text.getText().length()) {
                paragraph.add(text);
            }
        }

        /**
         * This method replaces all the newline characters by a space.
         */
        protected String strip(StringBuffer buf) {
            while (buf.length() != 0 && (buf.charAt(0) == '\n' || buf.charAt(0) == '\t')) {
                buf.deleteCharAt(0);
            }

            while (buf.length() != 0 && (buf.charAt(0) == '\n' || buf.charAt(0) == '\t')) {
                buf.deleteCharAt(buf.length() - 1);
            }

            return buf.toString();
        }
    }
}


FillWithUnderline C#

C#
using System;
using System.IO;
using System.Text;
using System.Xml;
using iText.Forms;
using iText.Forms.Fields;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;

namespace iText.Samples.Sandbox.Acroforms
{
    public class FillWithUnderline
    {
        public static readonly String DEST = "results/sandbox/acroforms/fill_with_underline.pdf";

        public static readonly String SRC = "../../../resources/pdfs/form.pdf";

        public static void Main(String[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();

            new FillWithUnderline().ManipulatePdf(DEST);
        }

        protected void ManipulatePdf(String dest)
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
            Document doc = new Document(pdfDoc);
            PdfAcroForm form = PdfFormCreator.GetAcroForm(pdfDoc, true);

            // If no fields have been explicitly included, then all fields are flattened.
            // Otherwise only the included fields are flattened.
            form.FlattenFields();

            Rectangle pos = form.GetField("Name").GetWidgets()[0].GetRectangle().ToRectangle();

            // Custom parser gets position of the form field
            // to fill in the document with the parsed content.
            CustomXmlParser parser = new CustomXmlParser(doc, pos);
            parser.Parse("<root><div>Bruno <u>Lowagie</u></div></root>");

            pdfDoc.Close();
        }

        private class CustomXmlParser
        {
            protected Document document;
            protected Rectangle position;
            protected Paragraph paragraph;

            // If isUnderlined flag is true, then parsed text should be underlined.
            protected bool isUnderlined;

            public CustomXmlParser(Document document, Rectangle position)
            {
                this.document = document;
                this.position = position;
                paragraph = new Paragraph();
                isUnderlined = false;
            }

            public void Parse(String line)
            {
                byte[] content = Encoding.UTF8.GetBytes(line);
                MemoryStream stream = new MemoryStream(content);
                using (XmlReader reader = XmlReader.Create(stream))
                {
                    while (reader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element)
                        {
                            
                            // If the node type is opening tag <u>, then set isUnderlined flag to true.
                            HandleStartElement(reader);
                        }
                        else if (reader.NodeType == XmlNodeType.Text)
                        {
                            
                            // Creates a iText.Layout.Element.Text instance from the text,
                            // got from the passed reader, and wraps it if not empty with a paragraph.
                            HandleText(reader);
                        }
                        else if (reader.NodeType == XmlNodeType.EndElement)
                        {
                            
                            // This method handles closing tags </div> and </u>:
                            // if the node type is closing tag </div>, then add the parsed text to the document
                            // if the node type is closing tag </u>, then set isUnderlined flag to false.
                            HandleEndElement(reader);
                        }
                    }
                }
            }

            private void HandleStartElement(XmlReader reader)
            {
                if (reader.Name == "u")
                {
                    isUnderlined = true;
                }
            }

            private void HandleEndElement(XmlReader reader)
            {
                if (reader.Name == "div")
                {
                    document.Add(paragraph.SetFixedPosition(position.GetLeft(),
                        position.GetBottom(), position.GetWidth()));

                    // Set the position of the next form field.
                    position.MoveDown(22);
                    paragraph = new Paragraph();
                }
                else if (reader.Name == "u")
                {
                    isUnderlined = false;
                }
            }

            private void HandleText(XmlReader reader)
            {
                Text text = new Text(reader.Value);
                if (isUnderlined)
                {
                    text.SetUnderline();
                }

                if (0 != text.GetText().Length)
                {
                    paragraph.Add(text);
                }
            }
        }
    }
}

Resources


JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.