如何用Node.js将多份PDF文件打包为.RAR文件并提供下载
Great question! To bundle all your project PDFs into a single RAR and download it, we'll need to modify both your Express backend and AngularJS frontend. Here's how to do it step by step:
Backend (Express) Modifications
First, since Node.js doesn't have native support for creating RAR files (RAR is a proprietary format), we'll use 7-Zip—a free tool that can handle RAR compression. Make sure it's installed on your server:
- On Linux: Run
sudo apt install p7zip-full - On Windows: Download from the official site and add it to your system PATH, or use the full path to
7z.exein your command.
Update routes.js
Add a new route that fetches all project PDF filenames, creates a RAR archive, and sends it for download. We'll also clean up the temporary RAR file after the download completes:
const fs = require('fs'); const path = require('path'); const { exec } = require('child_process'); // Import your Project model here (adjust the path as needed) const Project = require('./models/Project'); app.get('/api/download/all-archive', async function(req, res) { try { // Fetch all project documentation filenames from your database const projects = await Project.find({}, 'Documentation'); const pdfFilenames = projects .map(project => project.Documentation) .filter(filename => filename); // Remove any null/empty entries if (pdfFilenames.length === 0) { return res.status(404).send('No PDF files available to archive'); } // Define paths const uploadsDir = path.join(__dirname, 'public', 'uploads'); const tempRarPath = path.join(__dirname, 'temp_project_docs.rar'); // Build the list of PDF paths (escape spaces for filenames with spaces) const pdfPaths = pdfFilenames.map(filename => `"${path.join(uploadsDir, filename)}"`); const filesToArchive = pdfPaths.join(' '); // 7-Zip command to create a RAR archive // Adjust the 7z path if it's not in your system PATH (e.g., "C:\\Program Files\\7-Zip\\7z.exe" on Windows) const rarCommand = `7z a -tRAR "${tempRarPath}" ${filesToArchive}`; // Execute the 7-Zip command exec(rarCommand, (error, stdout, stderr) => { if (error) { console.error(`Error creating RAR archive: ${error.message}`); return res.status(500).send('Failed to generate the archive'); } if (stderr) { console.error(`7-Zip warnings: ${stderr}`); } // Send the RAR file as a download res.download(tempRarPath, 'all_project_docs.rar', (downloadErr) => { // Clean up the temporary RAR file after download fs.unlink(tempRarPath, (unlinkErr) => { if (unlinkErr) { console.error(`Failed to delete temporary RAR: ${unlinkErr.message}`); } }); }); }); } catch (dbError) { console.error(`Database error: ${dbError.message}`); res.status(500).send('Failed to fetch project files'); } }); // Keep your existing single file download route app.get('/api/download/archive/:filename', function(req,res){ res.download("public/uploads/"+req.params.filename, req.params.filename); });
Frontend (AngularJS) Modifications
Add a new function to your archive.js to trigger the bulk download route, and add a button in your UI to call it.
Update archive.js
// Keep your existing single file download function $scope.downloadPdf = function(obj){ $http.get('api/download/archive/'+obj.Documentation) .success(function(data){ window.open('api/download/archive/'+obj.Documentation); }); }; // Add this new function for bulk download $scope.downloadAllPdfsAsRar = function() { // Open the bulk archive route to trigger the download window.open('/api/download/all-archive'); };
Add a Download Button in Your HTML
Add a button to your project table or page to let users trigger the bulk download:
<button ng-click="downloadAllPdfsAsRar()" class="btn btn-primary"> Download All PDFs as RAR </button>
Key Considerations
- Permissions: Ensure your server has write access to the directory where you're creating the temporary RAR file, and read access to the
public/uploadsfolder. - Temporary File Cleanup: The code deletes the temporary RAR after download, but if a user cancels the download, the file might remain. Consider adding a periodic cleanup task (e.g., using
node-schedule) to remove old temp files. - Filename Spaces: The code escapes filenames with spaces using quotes, which works with 7-Zip.
- 7-Zip Path: If 7-Zip isn't in your system PATH, replace
7zin the command with the full path to the executable (e.g.,"C:\\Program Files\\7-Zip\\7z.exe"on Windows).
内容的提问来源于stack exchange,提问作者Vitali

