TCPDF生成PDF在安卓Firefox+Adobe Reader下载失败求助
The Problem
I’m using TCPDF to generate and prompt downloads of PDF contracts. My desktop code works perfectly:
header('Content-Type: application/pdf'); header('Content-Disposition: attachment; filename="contract-' . $prename . '-' . $name . '.pdf"'); exit($pdf->Output('contract-' . $prename . '-' . $name . '.pdf"', 'D'));
But on Android 10 with Firefox 68.7.0, users get an error message: "无法下载文件,请保存到本地存储后再尝试打开" (Can't download file; please save to local storage first before opening).
After digging into it, I found this is tied to Adobe Reader—if I remove Adobe Reader as Firefox’s default PDF handler, downloads work fine. Oddly, Chrome 81.0.4044.117 has no issues even with Adobe Reader set as default. It seems Firefox’s method of passing the PDF stream to Adobe Reader on Android is broken, and I need a fix that doesn’t force users to change their browser or app settings.
Quick note: Your original code has a syntax error in the
Outputcall—there’s an extra double quote at the end of the filename string. That could cause unexpected filename parsing issues, so fixing that should be your first small step.
What’s Causing This?
From my experience with similar cross-browser Android issues, the problem likely stems from how Firefox handles direct PDF streams with Adobe Reader. Unlike Chrome, Firefox might not properly buffer the PDF or send the right headers to let Adobe Reader accept the stream directly. Without clear file size info or proper caching headers, Adobe Reader rejects the incomplete data, triggering the download error.
Fixes to Try
Here are two tested solutions that work around this compatibility issue without requiring user changes:
Option 1: Stream the PDF with Explicit Content Length & Headers
This approach generates the PDF first, then sends it with headers that Firefox and Adobe Reader can reliably handle. The key addition is the Content-Length header, which tells the browser exactly how much data to expect:
// Generate the PDF as a string first (no immediate download) $pdfContent = $pdf->Output('', 'S'); // Fix the filename syntax error from your original code $filename = "contract-$prename-$name.pdf"; // Set robust headers for cross-browser compatibility header('Content-Type: application/pdf'); header('Content-Length: ' . strlen($pdfContent)); // Critical for Android Firefox header("Content-Disposition: attachment; filename=\"$filename\""); header('Cache-Control: public, must-revalidate, max-age=0'); header('Pragma: public'); header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Force immediate download by setting past expiry // Output the PDF content echo $pdfContent; exit;
By generating the PDF first and sending the exact content length, Firefox can properly stream the entire file to Adobe Reader without truncation, which resolves the "save to local storage" error.
Option 2: Save to a Temp File & Redirect
If streaming still causes issues, you can save the PDF to a temporary server location first, then redirect the user to the static file. This avoids direct stream handling between Firefox and Adobe Reader entirely:
// Create a unique temp filename to avoid conflicts $tempFilename = "contract-" . uniqid() . ".pdf"; $tempFilePath = sys_get_temp_dir() . "/" . $tempFilename; // Save the PDF to the temp file $pdf->Output($tempFilePath, 'F'); // Redirect the user to the temp file (adjust the URL to match your server's public path) header("Location: /path-to-temp-files/$tempFilename"); exit; // Important: Set up a cron job or cleanup script to delete old temp files regularly
This method lets Firefox handle the file as a standard static download, which Adobe Reader accepts without issues since it’s reading from a fully saved file instead of a live stream. Just make sure your temp directory is accessible via HTTP and you clean up old files to avoid storage bloat.
Why These Work
- Option 1 removes ambiguity about the file size, which Firefox on Android needs to properly hand off the stream to Adobe Reader.
- Option 2 bypasses the stream-handling conflict entirely by serving a static file, which all browsers and PDF readers handle consistently.
Testing
After implementing either fix, test on Android 10 + Firefox 68.7.0 with Adobe Reader set as the default PDF handler. You should no longer see the download error, and the solution will keep working on iOS, Chrome, and desktop browsers as well.
内容的提问来源于stack exchange,提问作者Vibe Design




