Create VDP files from PDF templates

pdfToolbox provides a search and replace for VDP Quick Fix which can be used for certain types of variable data printing. The Quick Fix is based on a PDF template with placeholder text and a JSON configuration file, which allows to create VDP data with individual text and graphic content (e.g. barcodes). 

TIP: if the placeholder text is not really unique and could occur elsewhere on the page, it should be supplemented by one or more ‘special’ character(s). E.g. "car" might occur elsewhere in the text on the page (e.g. in the word "careful"). Therefore, "$car" or "%car%" would be a better choice for the placeholder text.

Two options to run this Quick Fix

On Command line with a JSON configuration file

Use  --quickfix on the command line and add your JSON configuration file and the input file.

On pdfToolbox Desktop with the "JavaScript based configuration" Quick Fix

The "JavaScript based configuration" Quick Fix provides a text editor where the content of the JSON configuration file can be inserted. With this method, you can use the test mode for debugging.

NOTE: This Quick Fix configuration must always return a JavaScript object that contains the JSON serialisation:

let cfg = {

	… Your Quick Fix JSON serialisation 
};
cfg; //<- return JavaScript object

How to create a JSON file that replaces Text for VDP files

The following shows how to create VDP files with custom text and barcodes with the help of an example. The input file is a PDF with placeholder text that can be customized using a JSON configuration file.

To better understand the individual parameters of the JSON file, they are explained below:

Structure of the JSON

{ 
 "quickfixes": [
 {            
   "quickfix": "search_and_replace_for_VDP",            
   "version": 1.0,
   "instructions": [
     {                    
      "page_selector": "all",                    
      "search_scope": "TrimBox",                    
      "left": 0,                    
      "bottom": 0,                    
      "right": 0,                    
      "top": 0,                    
      "unit": "pt",                    
      "replacements": [],
      "font_locations":  {}
     }            
   ]
  }    
 ]
}

//		"page_selector": "all|even|odd|<splitscheme_expression>"
//		"search_scope": "all|MediaBox|CropBox|BleedBox|TrimBox|ArtBox|absolute"
//		"unit": "pt|mm|inch"

The parameters "page_selector", "search_scope", "left", "bottom", "right", "top" and "unit" are responsible for the pages and the page range where the text replacement should take place.

The "replacements" array

In the "replacements" array, the search and replace parameters are defined. The "operator" parameter can be used to specify the text to be searched for. Either you enter the exact text (Operator: equal to) or you use a RegEx expression which allows more complex search patterns (Operator: regex). More information about RegEx expressions can be found here.

Two types of content can be defined: Text and codes (e.g. QR codes, matrix codes). The "records" Array contains the data for the replacement text and/or barcode. Any number of records can be defined in an array. Based on these records, new pages are created during the Quick Fix execution. That means, for each "records" entry, a new page is added. Since there can be multiple "records" arrays, the largest array determines the number of duplications. If one of the "records" is only a string or one array is shorter than the longest array, the last value is repeated as many times as necessary.

Replace placeholder text with text

The replaced text has the same appearance as the placeholder text (font, size, color, etc.). The text alignment can be specified. Left/center/right  alignment does not change the width of the text. If "block_aligned" is selected, the text is compressed or stretched within limits.  

{
   "operator": "equal_to",
   "search_for": "$city",
   "records":  ["Madrid", "Amsterdam", "Berlin"],
   "alignments": "right_aligned"
},                       


//		"operator": "regex|equal_to"
//		"alignment": "right_aligned|left_aligned|center_aligned|block_aligned"

Replace placeholder text with barcodes

Placeholder text can also be replaced with a 1D or 2D code. The codes will be bottom aligned at the base line of the placeholder text. Left/center/right alignment will work in the same way as for text replacement.

{
   "operator": "equal_to",
   "search_for": "$qr",
   "records": ["8676780-h5s-dh5-7dh-jd7-xpK", "8676792-zxb-vb8-kb4-q78-aLf", "8676812-84H-1v2-ddG-ivh-uiV"], 
   "barcode":
   { 
     "type": "QR-Code",
     "width": "20mm",
     "height": "20mm",
     "modulewidth": "0.33mm",
     "textplacement": "below",
     "barwidthreduction": "0%",
     "quietzoneleft": "0",
     "quietzoneright": "0",
     "quietzoneunit": "pt"
   },                            
   "alignments": "right_aligned"                        
}


//		"operator": "regex|equal_to"
//		"textplacement": "above|below|none"
//		"quietzoneunit": "pt|mm|in|X|cm|m|ft|pc"
//		"alignment": "right_aligned|left_aligned|center_aligned"
//		"type": see link below (Supported Barcode symbologies)

A list of supported Barcode types can be found here: List of supported barcodes and matrix codes.

An explanation of the respective barcode object parameters (such as modulewidth, barwidthreduction or quietzoneleft) are listed in this article: Extended list of parameters for the barcode object.

Example for EAN 13 Code ("records" must contain a thirteen-digit number)
{
  "operator": "equal_to",
  "search_for": "$EAN",
  "records": ["1234567890128", "1234567890128", "1234567890128"],
  "barcode": 
  {
    "type": "EAN 13",
    "width": "50mm",
    "height": "15mm",
    "modulewidth": "0.33mm",
    "textplacement": "none",
    "barwidthreduction": "0%",
    "quietzoneleft": "0",
    "quietzoneright": "0",
    "quietzoneunit": "pt"
  },
  "alignments": "right_aligned"
}
Result:

The "font_locations" parameter

The "font_locations" parameter contains the data that is required for a successful font replacement. Here you can specify parameters that define where font files are located. If the PDF has all the necessary fonts fully embedded, the text replacement will not cause any missing glyphs problems. In other cases, you must specify which location should be searched by the engine, or you specify the fonts separately using a path.

{
   "in_fonts_folder_next_to_input_file": false,
   "in_any_folder_next_to_input_file": false, 
   "next_to_input_file": false,
   "in_user_fonts_folder": false,
   "in_system_fonts_folder": false, 
   "use_paths": false,
   "paths": [ 
      "../some_folder"
   ]                        
}

Result

Since three records were defined in the JSON configuration file for each placeholder, the output file contains three pages with individual text: