Fondo
Estoy usando Puppeteer en una aplicación Express que se ejecuta en una imagen de Docker. Es necesario que ejecutemos en Docker debido a las dependencias necesarias que necesita Debian y que no tenemos acceso para instalar. Usar Docker nos permite instalar lo que necesitamos.
Hemos visto a muchas personas tener problemas para que sus fuentes se muestren correctamente en los archivos PDF y, en todos los casos que he visto, instalar la fuente de una manera similar siempre es la respuesta.
apt-get install -yq --allow-unauthenticated ttf-mscorefonts-installer En ese caso, están instalando fuentes específicas para las que resulta que hay un apt-get . He visto a otros instalar las fuentes predeterminadas de Puppeteer con RUN apt-get install -yyq fonts-liberation también.
Ejemplo de código
const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'], ignoreHTTPSErrors: true, dumpio: false, }); const page = await browser.newPage(); await page.goto( `http://localhost:3000/${template}?data=${JSON.stringify(req.body)}`, ); const pdfBuffer = await page.pdf({ format: 'A4', margin: { top: '20px', left: '20px', right: '20px', bottom: '20px', }, }); await browser.close();Problema
Necesitamos instalar alrededor de 10 fuentes que las diferentes partes de la aplicación usarán en diferentes ocasiones. Tenemos los archivos ttf y woff para esto. Decidimos agregarlas al sistema de la manera que parece ser lo que está haciendo apt-get con las otras fuentes que hemos visto instalar. Hicimos esto agregando nuestras fuentes al directorio de Debian,
/usr/local/share/fuentes
Podemos ver que las fuentes están configuradas correctamente en el sistema ejecutando,
fc-listCuando agregamos las fuentes como esta, no se procesan. En cambio, obtenemos símbolos extraños donde deberían estar estas fuentes.
Ejemplo
Estamos agregando nuestras fuentes de esta manera usando Dockerfile,
RUN apt-get install -yyq fonts-liberation COPY /fonts/*.ttf /usr/local/share/fonts/ COPY /fonts/*.woff /usr/local/share/fonts/Pregunta
Dado que tenemos un montón de archivos de fuentes ttf y woff que deben representarse en PDF con Puppeteer, ¿cuál es la forma correcta de agregarlos a nuestra imagen de Debian que se ejecuta en Docker para que Puppeteer los use como se espera?
Este es un script de muestra que va y captura la captura de pantalla y el pdf en el sitio web. Ambos tienen el mismo propósito en esta pregunta, para mostrar el funcionamiento de las fuentes.
(async()=>{ const puppeteer = require('puppeteer') const browser = await puppeteer.launch({ headless: true, args: ["--no-sandbox", "--disable-setuid-sandbox"] }); const page = await browser.newPage() await page.goto('https://jp.quora.com/') await page.screenshot({path: `/shared/_${Date.now()}.png`}) const pdfBuffer = await page.pdf({path: `/shared/_${Date.now()}.pdf`}); await browser.close() })()Aquí está el dockerfile mínimo, esto es muy mínimo, no incluye nada adicional como dumb-init y varios trucos de limpieza, ya que no es necesario aquí.
FROM node:8 # Install dependencies RUN apt-get update && \ apt-get -yq install libatk1.0-0 libgtk2.0-0 libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 libasound2 xauth xvfb # Cd into /app WORKDIR /app # Copy package.json into app folder COPY package.json /app # Install dependencies RUN npm install COPY . /app # Start script on Xvfb CMD ["xvfb-run","npm","start"]Al ejecutarse, así es como se muestra la Quora japonesa en el titiritero, se muestra así porque faltan las fuentes.
Dado que está basado en jessie, podemos instalar fuentes usando algunos comandos diferentes.
A continuación se instalarán algunas fuentes con caracteres japoneses.
RUN apt-get -yq install xfonts-utils fonts-droid xfonts-intl-asianSi tengo las fuentes dentro del directorio de fuentes, entonces el comando es,
COPY fonts/*.* /usr/share/fonts/truetype/Eso es muy sencillo. Sin embargo, las fuentes seguirán sin funcionar porque la caché de fuentes no se actualiza lo suficientemente rápido. Agregar lo siguiente asegurará que esté actualizado.
RUN mkfontscale && mkfontdir && fc-cache¡Eso es todo! Ejecutemos el script de nuevo.
A partir de 2022 y Puppeteer 13, la lista de dependencias es la que se indica en el manual de solución de problemas de titiritero:
sudo apt-get install fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttfEn Chrome sin cabeza para tomar una captura de pantalla: