Я хочу щелкнуть внизу и скачать файл excel, но не могу понять, почему он не работает.
основная проблема на стороне маршрутизатора tRPC.
инструмент, который я использую:
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);
},
});
Внешний интерфейс:
function Print() {
const xlsxMutation = trpc.useMutation(['guest.xlsx'])
const onDownload = React.useCallback(()=>{
xlsxMutation.mutate({
id:"test"
})
},[xlsxMutation])
return (
<>
<button onClick = {()=>handleClickOpen()}>download</button>
</>
);
}
codeandbox еще не установил ExcelJS, потому что я не уверен, почему появляется ошибка.
в любом случае, он имитировал мою структуру кода.
кто-нибудь, использующий NextJS tRPC и ExcelJS, делится кодом.
##редактировать
поскольку файл xlsx уже существует (FILE_PATH), я должен что-то вроде ctx.res.pipe()
верно? но как??
не уверен, что этот подход правильный или нет, прочитайте документ о Blob, затем поймите, как сервер и клиент преобразовывают данные, такие как изображения или файлы pdf и т. д., поэтому я выбираю этот путь.
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")}
},
});
внешний интерфейс:
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>
</>
);
}
в основном, сторона маршрутизатора отправляет обратно файл excel, преобразованный в base64, fontend получает данные base64 для преобразования обратно в файл xlsx.
обратитесь к :