Reputation: 395
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);
}
}
Upvotes: 1
Views: 12323
Reputation: 95898
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.
E.g.
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.
Upvotes: 4