Skip to content

Not able to add text color  #1668

@AdiTya-DiXiT-01

Description

@AdiTya-DiXiT-01

What are you working on?

I'm having trouble adding text color to text fields in my PDF documents using the pdf-lib library in my Angular project. Below is a snippet of my code for context.

Code Snippet:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import * as XLSX from 'xlsx';
import { degrees, PDFDocument, PDFPage, rgb, TextAlignment } from 'pdf-lib';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import QRCode from 'qrcode';
import fontkit from '@pdf-lib/fontkit';

@Component({
  selector: 'app-certificate-form',
  templateUrl: './certificate-form.component.html',
  styleUrls: ['./certificate-form.component.css'],
  standalone: true,
  imports: [CommonModule, FormsModule],
})
export class CertificateFormComponent implements OnInit {
  pdfFile: File | null = null;
  excelFile: File | null = null;
  pdfFields: string[] = [];
  excelFields: string[] = [];
  fieldMapping: { [key: string]: string } = {};
  dataEntries: any[] = [];
  textFieldProperties!: any[];

  constructor(private router: Router) {
    const navigation = this.router.getCurrentNavigation();
    const state = navigation?.extras.state as {
      pdfFile: File;
      excelFile: File;
      textFieldProperties: any[];
    };
    this.pdfFile = state?.pdfFile || null;
    this.excelFile = state?.excelFile || null;
    this.textFieldProperties = state?.textFieldProperties || [];
  }

  ngOnInit() {
    if (this.pdfFile) {
      this.loadPDFTextFields();
    }

    if (this.excelFile) {
      this.loadExcelFields();
    }
  }

  async loadPDFTextFields() {
    if (this.pdfFile) {
      const reader = new FileReader();
      reader.onload = async (e: any) => {
        const pdfData = new Uint8Array(e.target.result);
        const pdfDoc = await PDFDocument.load(pdfData);
        const form = pdfDoc.getForm();
        this.pdfFields = form.getFields().map((field) => field.getName());
        console.log('PDF Fields:', this.pdfFields);
      };
      reader.readAsArrayBuffer(this.pdfFile);
    }
  }

  loadExcelFields() {
    if (this.excelFile) {
      const reader = new FileReader();
      reader.onload = (e: any) => {
        try {
          const data = new Uint8Array(e.target.result);
          const workbook = XLSX.read(data, { type: 'array' });

          const sheetName = workbook.SheetNames[0];
          const worksheet = workbook.Sheets[sheetName];

          const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });

          this.excelFields = jsonData[0] as string[];
          this.dataEntries = jsonData.slice(1);
        } catch (error) {
          console.error('Error reading Excel file:', error);
        }
      };
      reader.readAsArrayBuffer(this.excelFile);
    }
  }

  async generateCertificates() {
    if (this.pdfFile && this.dataEntries.length > 0) {
      for (const entry of this.dataEntries) {
        const pdfDoc = await PDFDocument.load(await this.pdfFile!.arrayBuffer());
        const form = pdfDoc.getForm();

        for (const [pdfField, excelField] of Object.entries(this.fieldMapping)) {
          const fieldIndex = this.excelFields.indexOf(excelField);
          if (fieldIndex >= 0) {
            let fieldValue = entry[fieldIndex];
            if (typeof fieldValue !== 'string') {
              fieldValue = String(fieldValue);
            }

            const textField = form.getTextField(pdfField);
            const fieldProperties = this.textFieldProperties.find((prop) => prop.name === pdfField);
            if (fieldProperties) {
              const { font, fontSize, alignment, textColor, multiline } = fieldProperties;

              pdfDoc.registerFontkit(fontkit);
              const fontBytes = await fetch(`../../assets/fonts/${font}.ttf`).then((res) => res.arrayBuffer());
              const customFont = await pdfDoc.embedFont(fontBytes);

              multiline ? textField.enableMultiline() : textField.disableMultiline();
              textField.setText(fieldValue);

              const [widget] = textField.acroField.getWidgets();
              widget.getOrCreateBorderStyle().setWidth(0);
              textField.setFontSize(fontSize);
              textField.setColor(textColor); // This is where I'm having issues

              if (alignment === 'Center') {
                textField.setAlignment(TextAlignment.Center);
              } else if (alignment === 'Left') {
                textField.setAlignment(TextAlignment.Left);
              } else {
                textField.setAlignment(TextAlignment.Right);
              }
              textField.updateAppearances(customFont);
            }
          }
        }

        form.flatten();

        const pdfBytes = await pdfDoc.save();
        const blob = new Blob([pdfBytes], { type: 'application/pdf' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `${entry[1]}.pdf`;
        a.click();
        URL.revokeObjectURL(url);
      }
    }
  }
  // Additional methods omitted for brevity
}

Issue

I am currently unable to set the text color in text fields using the pdf-lib library. Specifically, I'm trying to apply a color to the text field by calling textField.setColor(textColor);, but it doesn't seem to work as expected. The textColor variable is supposed to be an RGB color value (e.g., rgb(1, 0, 0) for red), but the text color in the output PDF remains unchanged.

Additional Notes

I'm working on an application that generates PDF forms on a web page and needs to customize various properties of text fields, including text color.

Any help or suggestions would be greatly appreciated!


Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions