简体   繁体   English

ExcelJs 使用 tRPC 路由器下载 xlsx 文件

[英]ExcelJs download xlsx file with tRPC router

I want to click the bottom and download the excel file, but I can't figure out why it is not working.我想点击底部并下载excel文件,但我不知道为什么它不起作用。
the main problem is at tRPC router side.主要问题出在 tRPC 路由器端。

the tool I using:我使用的工具:

  1. T3 T3
  2. ExcelJs ExcelJs

tRPC router: tRPC 路由器:

  .mutation("xlsx", {
    input: z.object({
      id: z.string(),
    }),
    resolve: async ({ ctx }) => {
      const FILE_PATH = "./src/utils/01.xlsx";

      const wb = new ExcelJs.Workbook();
      await wb.xlsx.readFile(FILE_PATH).then(() => {
        var ws = wb.getWorksheet(1);
        ws.getCell("H4").value = "fkfk";
      });

      return wb.xlsx.write(ctx.res);
    },
  });

Frontend:前端:

function Print() {

  const xlsxMutation = trpc.useMutation(['guest.xlsx'])

  const onDownload = React.useCallback(()=>{
    xlsxMutation.mutate({
      id:"test"
    })
  },[xlsxMutation])


  return (
    <>
    <button onClick={()=>handleClickOpen()}>download</button>
   
    </>
   
  );
}

CodeSandBox 代码沙盒

the codesandbox not install ExcelJS yet, because I'm not sure why the error show up.代码框尚未安装 ExcelJS,因为我不确定为什么会出现错误。
anyway, it simulated my code structure.无论如何,它模拟了我的代码结构。

is there anyone using NextJS tRPC and ExcelJS share the code.有没有人使用 NextJS tRPC 和 ExcelJS 共享代码。

##edit ##编辑
since the xlsx file already exist (FILE_PATH), I should something like ctx.res.pipe() right?由于 xlsx 文件已经存在(FILE_PATH),我应该像ctx.res.pipe()对吗? but how??但如何?

not sure this approach is right or not, read the document about Blob ,then understand how server and client Transformers data like image or pdf files and so on, so I choose this way.不确定这种方法是否正确,请阅读有关Blob的文档,然后了解服务器和客户端 Transformers 数据如何像图像或 pdf 文件等,所以我选择这种方式。

tRPC: tRPC:

  .mutation("xlsx", {
    input: z.object({
      id: z.string(),
    }),
    resolve: async ({ ctx }) => {

      const wb = await new ExcelJs.Workbook();
      await wb.xlsx.readFile(PUBLIC_FILE_PATH).then(() => {
        var ws = wb.getWorksheet(1);
        ws.getCell("H4").value = "OKM";
      });



      await wb.xlsx.writeFile(PUBLIC_FILE_PATH);

      const stream = fs.readFileSync(PUBLIC_FILE_PATH);

      return {xxx:stream.toString("base64")}

     
    },
  });

frontend:前端:

function Print() {
  const xlsxMutation = trpc.useMutation(["guest.xlsx"]);

  const onDownload = React.useCallback(() => {
    xlsxMutation.mutate({
      id: "test",
    });
  }, [xlsxMutation]);
  const [open, setOpen] = React.useState(true);

  const handleClickOpen = () => {
    onDownload();
    if (!xlsxMutation.data) return;
    const mediaType =
      "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,";

    window.location.href = `${mediaType}${xlsxMutation.data.xxx}`;
  };

  const handleClose = () => {
    setOpen(false);
  };
  return (
    <>
      <button onClick={() => handleClickOpen()}>Download</button>
    </>
  );
}

basically, the router side sends back the excel file converted to base64, fontend got the base64 data to convert back to xlsx file.基本上,路由器端发回excel文件转换为base64,fontend得到base64数据转换回xlsx文件。

refer to:参考:

  1. enter link description here 在此处输入链接描述
  2. Downloading Excel.xlsx saves base64 string in file 下载 Excel.xlsx 将 base64 字符串保存在文件中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM