gitbrent / PptxGenJS

Create PowerPoint presentations with a powerful, concise JavaScript API.
https://gitbrent.github.io/PptxGenJS/
MIT License
2.62k stars 611 forks source link

feat: support embed fonts #1302

Open Maxpsc opened 8 months ago

Maxpsc commented 8 months ago

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

ChillyBots commented 6 months ago

excited

Rigorich commented 4 months ago

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,
        })
    );
  12. 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);