wyozi / react-pptx

Create PowerPoint presentations with React
https://wyozi.github.io/react-pptx/
MIT License
129 stars 31 forks source link

Simple way to download the PPTX file #701

Open lamngo255 opened 1 month ago

lamngo255 commented 1 month ago

Thank you for creating this helpful library. I’m interested in the preview and download features for the generated PPTX files. After reviewing the demo code, I noticed it involves transpiling from the Monaco editor to a document and then using ReactPPTX to render the document into a .pptx file. However, my use case is simpler as I don’t require the Monaco editor. Is there a more straightforward way to achieve this?

wyozi commented 1 month ago

check the first code snippet in README. That's all you need to do to generate a pptx file. Monaco is just for demo purposes

lamngo255 commented 1 month ago

If I do like that, it won't render to the screen, can you show a react component example where the render function is used?

image
lamngo255 commented 1 month ago

I use another way to trigger download function, can see the preview now, but clicking on the download button won't do anything. Would appreciate if you can give me some pointers to resolve this issue, thanks!

"use client";
import React from "react";
import { Presentation, Shape, Slide, Text, render } from "react-pptx";
import Preview from "react-pptx/preview";
import fs from "fs";

const Page: React.FC = () => {
  const handleDownload = () => {
    render(
      <Presentation>
        <Slide>
          <Text
            style={{
              x: 3,
              y: 1,
              w: 3,
              h: 0.5,
              fontSize: 32,
            }}
          >
            Hello there!
          </Text>
          <Shape
            type="rect"
            style={{
              x: 3,
              y: 1.55,
              w: 3,
              h: 0.1,
              backgroundColor: "#FF0000",
            }}
          />
        </Slide>
      </Presentation>
    ).then((buffer) => {
      fs.writeFile("presentation.pptx", buffer as Buffer, () => {
        console.log("File saved successfully");
      });
    });
  };

  return (
    <div className="flex flex-col h-screen w-full overflow-hidden">
      <div className="flex flex-col h-full w-full overflow-hidden text-black bg-[#f5f7f9]">
        <button
          onClick={handleDownload}
          className="bg-blue-500 text-white w-40"
        >
          Download
        </button>
        <Preview>
          <Presentation>
            <Slide>
              <Text
                style={{
                  x: 3,
                  y: 1,
                  w: 3,
                  h: 0.5,
                  fontSize: 32,
                }}
              >
                Hello there!
              </Text>
              <Shape
                type="rect"
                style={{
                  x: 3,
                  y: 1.55,
                  w: 3,
                  h: 0.1,
                  backgroundColor: "#FF0000",
                }}
              />
            </Slide>
          </Presentation>
        </Preview>
      </div>
    </div>
  );
};

export default Page;
lamngo255 commented 1 month ago

Oh, I realize that if I rewrite the handleDownload function above like this, it's working fine. But still wonder how the fs.writeFile function didn't work as expected.

const handleDownload = async () => {
    try {
      const buffer = await render(
        <Presentation>
          <Slide>
            <Text
              style={{
                x: 3,
                y: 1,
                w: 3,
                h: 0.5,
                fontSize: 32,
              }}
            >
              Hello there!
            </Text>
            <Shape
              type="rect"
              style={{
                x: 3,
                y: 1.55,
                w: 3,
                h: 0.1,
                backgroundColor: "#FF0000",
              }}
            />
          </Slide>
        </Presentation>,
        { outputType: "blob" }
      );

      const url = URL.createObjectURL(buffer as Blob);
      const link = document.createElement("a");
      link.href = url;
      link.download = "presentation.pptx";
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
    } catch (error) {
      console.error("Error generating presentation:", error);
    }
  };
wyozi commented 1 month ago

yeah, fs is not available to the browser so you need to use the <a> method for it