Skip to content

Using non-latin characters in PDF output

There are certain places in CiviCRM where PDF output will contain ? instead of the appropriate character because the DejaVu unicode font files have been removed from the DOMPDF library. For example CiviCRM uses DOMPDF when producing PDF copies of CiviReports, but it uses a different library (TCPDF) for Mailing Labels, which does have the DejaVu fonts.

In Drupal 9, the entire DOMPDF library is downloaded during install, so it will work with most unicode characters as-is. But if you need CJK characters DejaVu does not contain those, so you will need to install another font file such as SimSun using the steps below.

Note when testing to see if you've succeeded, use letters that are entirely outside the character set included in the basic font files, e.g. use cyrillic letters such as д. Several letters like ü will work either way so aren't a good test.

Option A: Install the unicode font files for DOMPDF

Note - except for CJK character support below these steps are done for you if you install dompdf-fonts

  1. Download the dompdf zip file from the github repository.
  2. Create a folder in a location that won't get overwritten when you upgrade, e.g. sites/default/fonts for Drupal.
  3. Extract all the DejaVu files, including the DejaVu-XXX.ufm files as well as the .ttf files, from the lib/fonts subfolder in the zip file into the folder you created.
  4. In the folder you created, create a file called dompdf_font_family_cache.php and put this in it. Don't replace $fontDir with anything leave it as that variable.
    <?php return [
      'dejavu sans' => [
        'bold' => $fontDir . '/DejaVuSans-Bold',
        'bold_italic' => $fontDir . '/DejaVuSans-BoldOblique',
        'italic' => $fontDir . '/DejaVuSans-Oblique',
        'normal' => $fontDir . '/DejaVuSans',
      ],
      'dejavu sans mono' => [
        'bold' => $fontDir . '/DejaVuSansMono-Bold',
        'bold_italic' => $fontDir . '/DejaVuSansMono-BoldOblique',
        'italic' => $fontDir . '/DejaVuSansMono-Oblique',
        'normal' => $fontDir . '/DejaVuSansMono',
      ],
      'dejavu serif' => [
        'bold' => $fontDir . '/DejaVuSerif-Bold',
        'bold_italic' => $fontDir . '/DejaVuSerif-BoldItalic',
        'italic' => $fontDir . '/DejaVuSerif-Italic',
        'normal' => $fontDir . '/DejaVuSerif',
      ],
    ];
    
  5. Visit Administer - System Settings - Misc and in the field for DOMPDF Font Folder put the full path to the font folder you created.
  6. When composing the PDF, if you have pasted from Microsoft Word into CKEditor it might set a specific font and then you will still see ? in the output. You can click the Source button on the CKEditor toolbar to check - look for e.g. <p style="font-family: Arial;">.

Additional steps for CJK or an alternate unicode font

  1. You will need to use the load_font utility from https://github.com/dompdf/utils. Download and extract it into some temporary folder.
  2. Edit the require line near the top of the load_font.php file and set it to the path to your CiviCRM installation's vendor/autoload.php.
  3. Uncomment and edit the $fontDir line near the top of the load_font.php file and set it to the fonts folder you created earlier for DejaVu.
  4. Copy the .ttf font file you want to use into the folder where load_font.php is.
  5. Run php load_font.php font_name font_file.ttf, where you replace the last two as appropriate for the font you are installing, e.g. php load_font.php SimSun simsun.ttf.
  6. Note this will overwrite the dompdf_font_family_cache.php file you created earlier for DejaVu, so to also have DejaVu you will now need to edit the file and copy the php array from earlier back in.
  7. Now you no longer need the load_font utility or its folder and can delete it.
  8. Unlike with DejaVu which CiviCRM sets as the default font, you will need to specify the font when composing the PDF in the places where you use the CJK characters. You can use the Source button in CKEditor to do this and type it directly into the HTML: e.g. <p style="font-family: simsun;">的</p>
Option B: Install wkhtmltopdf instead

This may also have an advantage for reports that cause DOMPDF to run out of memory. A possible disadvantage is the output may not be exactly the same or as well tested with CiviCRM as DOMPDF since it is not the default. You only need to do this once.

  1. Your operating system's package manager may already make it available to install. If not then go to https://wkhtmltopdf.org and download the file for your operating system.
  2. Note the full path to the executable binary.
  3. In CiviCRM go to Administer - System Settings - Misc.
  4. A couple lines down there is a setting Path to wkhtmltopdf executable.
  5. Fill it in, e.g. /usr/local/bin/wkhtmltopdf
  6. Click the Save button.