简体   繁体   中英

How to set the text of a PDTextbox to a color?

I would like a PDTextbox to have Red text. I'm able to write out Red text, and I can set the value of a textbox, but I'm not sure how to set the textbox content to the color Red.

ie.

if (field instanceof PDTextbox) {
    field.setValue(field.getPartialName());
    //SOME WAY TO SET COLOR HERE?

Here is the test code I'm using:

package com.circumail;

import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDTextbox;

public class Test {

  public static void main(String[] args) throws Exception {
    File file = new File("c://temp//Work_Comp_App-Acord_130 fillv2.pdf");
    System.out.println("exists= " + file.exists());

    // Load the pdfTemplate
    PDDocument pdfDoc = PDDocument.load(file);
    PDDocumentCatalog docCatalog = pdfDoc.getDocumentCatalog();
    PDAcroForm acroForm = docCatalog.getAcroForm();

    // Get field names
    List<PDField> fieldList = acroForm.getFields();
    List<PDPage> pages = pdfDoc.getDocumentCatalog().getAllPages();
    for (PDPage page : pages) {
      // PDPageContentStream contentStream = new PDPageContentStream(pdfDoc, firstPage, true, false);
      PDPageContentStream contentStream = new PDPageContentStream(pdfDoc, page, true, true, true);
      processFields(acroForm, fieldList, contentStream);
      contentStream.close();
    }

    // Save edited file
    pdfDoc.save("c://temp//Work_Comp_App-Acord_130 fillv2 out.pdf");
    pdfDoc.close();
  }

  private static void processFields(PDAcroForm acroForm, List<PDField> fieldList, PDPageContentStream contentStream) throws IOException {
    for (PDField field : fieldList) {
      if (field instanceof PDTextbox) {
        field.setValue(field.getPartialName());
      }else{
        PDRectangle rect = getOffsetRectangle(field);
        //set text color to RED - not sure if I neet to set this back, can't get original color by calling contentStream.getNonStrokingColor()
        contentStream.setNonStrokingColor(Color.RED);
        contentStream.beginText();
        contentStream.setFont(PDType1Font.HELVETICA_BOLD, 8);
        contentStream.moveTextPositionByAmount(rect.getLowerLeftX(),rect.getLowerLeftY());
        contentStream.drawString( field.getPartialName());
        contentStream.endText();
      }
    }
  }

  private static PDRectangle getOffsetRectangle(PDField field) {
    COSDictionary fieldDict = field.getDictionary();
    COSArray fieldAreaArray = (COSArray) fieldDict.getDictionaryObject(COSName.RECT);
    PDRectangle rect = new PDRectangle(fieldAreaArray);

    //move the text up and to the right a bit
    int extra = 10;
    float x = rect.getLowerLeftX()+ extra;
    float y = rect.getLowerLeftY() + extra;
    float width = rect.getUpperRightX() + extra;
    float height = rect.getUpperRightY()+ extra;
    rect = new PDRectangle(new BoundingBox(x, y, width, height));
    return rect;
  }

  private static void printRect(final PDPageContentStream contentStream, final PDRectangle rect) throws IOException {
    contentStream.setStrokingColor(Color.YELLOW);
    contentStream.drawLine(rect.getLowerLeftX(), rect.getLowerLeftY(), rect.getLowerLeftX(), rect.getUpperRightY()); // left
    contentStream.drawLine(rect.getLowerLeftX(), rect.getUpperRightY(), rect.getUpperRightX(), rect.getUpperRightY()); // top
    contentStream.drawLine(rect.getUpperRightX(), rect.getLowerLeftY(), rect.getUpperRightX(), rect.getUpperRightY()); // right
    contentStream.drawLine(rect.getLowerLeftX(), rect.getLowerLeftY(), rect.getUpperRightX(), rect.getLowerLeftY()); // bottom
    contentStream.setStrokingColor(Color.BLACK);
  }

}

Normally a text field has a default appearance entry from which PDFBox constructs the appearance. Thus, you merely need to change this default appearance to also include a statement selecting red color.

Eg

PDDocument pdfDoc = PDDocument.load(SOURCE);
PDDocumentCatalog docCatalog = pdfDoc.getDocumentCatalog();
PDAcroForm acroForm = docCatalog.getAcroForm();

for (Object field : acroForm.getFields())
{
    if (field instanceof PDVariableText)
    {
        COSDictionary dict = ((PDField)field).getDictionary();
        COSString defaultAppearance = (COSString) dict.getDictionaryObject(COSName.DA);
        if (defaultAppearance != null)
            dict.setString(COSName.DA, defaultAppearance.getString() + " 1 0 0 rg ");

        field = field instanceof PDTextbox ? new PDTextbox(acroForm, dict) : new PDChoiceField(acroForm, dict);
        ((PDField)field).setValue(VALUE);
    }
}
pdfDoc.save(TARGET);
pdfDoc.close();

This code first enhances the default appearance and then sets the field value. The field variable has to be renewed in between because PDVariableText stores the default appearance in a hidden member during initialization.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM