如何在Angular4中用Kendo FileSaver在服务器指定目录生成PDF
Hey there! Let's tackle your problem right away. Your current code is set up to trigger a browser download for the PDF, but saving it directly to a folder on your web host requires shifting this logic to your backend server—front-end code can't write files to your server's filesystem for security reasons. Here's how to make this work:
Step 1: Adjust Your Front-End Code
Instead of using saveAs to download the PDF, send the data needed to generate the PDF to a backend API endpoint. This way, the server can handle the file creation and storage.
const options = <PDFOptions>{ paperSize: "A4", landscape: false }; const ReportName = GenerateGUID(); // Send PDF generation data to your backend fetch('/api/save-pdf', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ group: group, options: options, reportName: ReportName }) }) .then(response => response.json()) .then(data => { console.log('PDF saved to server successfully!', data); // Add user feedback here (e.g., a toast notification) }) .catch(error => { console.error('Failed to save PDF:', error); });
Step 2: Build the Back-End Endpoint
You'll need a backend route that receives the data, generates the PDF, and saves it to your target folder. Below is an example using Node.js/Express (adjust this to match your backend tech stack like ASP.NET, PHP, etc.):
First, install required dependencies (if using Node.js):
npm install express pdf-lib
Then create the API route:
const express = require('express'); const router = express.Router(); const { PDFDocument } = require('pdf-lib'); const fs = require('fs'); const path = require('path'); router.post('/api/save-pdf', async (req, res) => { try { const { group, options, reportName } = req.body; // Replace this with your actual PDF generation logic // (match what your front-end's `exportPDF` function does) const pdfDoc = await PDFDocument.create(); // Set page size based on your options const pageDimensions = options.paperSize === 'A4' ? [595.28, 841.89] // A4 portrait dimensions in points : [841.89, 595.28]; // A4 landscape const page = pdfDoc.addPage(pageDimensions); // Add content to the PDF using your `group` data page.drawText(`Report: ${reportName}`, { x: 50, y: pageDimensions[1] - 50 }); // Add more content (tables, charts, etc.) based on your `group` data here // Generate PDF binary data const pdfBytes = await pdfDoc.save(); // Define the server folder where you want to save the PDF const targetFolder = path.join(__dirname, '../server-reports'); // Adjust this path const savePath = path.join(targetFolder, `${reportName}.pdf`); // Create the folder if it doesn't exist if (!fs.existsSync(targetFolder)) { fs.mkdirSync(targetFolder, { recursive: true }); } // Write the PDF file to the server fs.writeFileSync(savePath, pdfBytes); res.json({ success: true, message: 'PDF saved successfully', filePath: savePath }); } catch (error) { console.error('Error processing PDF:', error); res.status(500).json({ success: false, error: 'Failed to generate and save PDF' }); } }); module.exports = router;
Critical Notes to Remember
- File Permissions: Ensure your backend server has write access to the target folder. For Linux servers, you may need to run
chmodor adjust folder ownership to let the server process write files. - PDF Generation Logic: Replace the sample PDF creation code with the actual logic from your front-end's
exportPDFfunction. Use a backend-compatible PDF library that matches your needs (e.g.,wkhtmltopdffor HTML-to-PDF,jsPDFfor Node.js, oriTextSharpfor .NET). - Security: Sanitize user-provided data (like
reportName) to prevent path traversal attacks. For example, remove special characters or validate that the filename doesn't contain../to avoid writing files outside your target folder.
内容的提问来源于stack exchange,提问作者Tarun Sharma

