PptxGenJS icon indicating copy to clipboard operation
PptxGenJS copied to clipboard

feat: support embed fonts

Open Maxpsc opened this issue 2 years ago • 2 comments

Through the new API addFonts, support embedding fonts into .ppt file.

Maxpsc avatar Nov 02 '23 09:11 Maxpsc

excited

ChillyBots avatar Jan 03 '24 16:01 ChillyBots

As it pointed out in https://github.com/gitbrent/PptxGenJS/issues/176, PowerPoint convert TTF/OTF font to it's own format FntData. So, as I tested, this PR doesn't work with TTF/OTF directly (there's error when opening presentation), but works with .fntdata files extracted from created manually PPTX with embedded fonts. Sadly, it's impossible to "embed only used symbols" in advance. And also embedded fonts work only in PowerPoint (and Aspose.Slides)

But if you still want to embed full font using this PR, here's instruction:

  1. Locally install font you want to embed
  2. Create new PowerPoint Presentation
  3. View - Slide Master - Fonts
  4. Replace Heading/Body fonts with your font name
  5. File - Options - Save - Embed fonts in the file - Embed all characters
  6. Save presentation
  7. Change file extension from .pptx to .zip
  8. Open .zip - ppt - fonts
  9. Copy this single .fntdata file outside of zip
  10. Convert this file to base64 string using any online converter
  11. Embed font using code below
const fontBase64 = '...';
fetch(`data:application/octet-stream;base64,${fontBase64}`)
	.then(res => res.blob())
	.then(blob =>
		this.presentation.addFont({
			typeface: 'My Font Name',
			fontBlob: blob,
		})
	);
  1. Save your presentation using base64 after any timeout
setTimeout(() =>
	this.presentation.write('base64')
		.then((data) => {
			// open index.html to get presentation
			const downloadLink = document.createElement('a');
			downloadLink.href = `data:application/octet-stream;base64,${data}`;
			downloadLink.download = `TEST - ${new Date().toISOString()}.pptx`;
			downloadLink.click();
		})
		.catch((err) => {
			console.error(err);
		})
, 0);

Rigorich avatar Mar 01 '24 09:03 Rigorich

I faced the same problem where PPTX generated by pptxgenjs could not embed custom fonts.
To solve this, I created a small extension library that adds font embedding support to pptxgenjs.

GitHub: pptx-embed-fonts

Example


import pptxgenjs from "pptxgenjs";
import { withPPTXEmbedFonts } from "pptx-embed-fonts/pptxgenjs";

const pptxgen = withPPTXEmbedFonts(pptxgenjs);

const pptx = new pptxgen();

const fontFile = await fetch("/font.ttf").then((res) => res.arrayBuffer());

const fontInfo = pptx.getFontInfo(fontFile);
const fontFace =
  fontInfo.names.fontFamily.en || fontInfo.names.fontFamily.zh;

pptx.addFont({
  fontFace: fontFace,
  fontType: "ttf",
  fontFile: fontFile,
});

const slide = pptx.addSlide();

slide.addText("Hello World 你好啊", {
  x: 0,
  y: 1,
  w: "100%",
  h: 2,
  align: "center",
  color: "0088CC",
  fontSize: 24,
  fit: "shrink",
  fontFace: fontFace,
});

const pptxFile = await pptx.writeFile({
  fileName: "example.pptx",
});

liyao1520 avatar Aug 14 '25 07:08 liyao1520