Laravel文件上传问题:获取原文件及恢复docx格式下载
It looks like the issue stems from two key problems: your uploaded .docx files are being stored without their original extension (hence the .file label), and you need to ensure the download process sends the file with the correct format headers. Here's how to resolve both:
Step 1: Store the File with Original Extension
Laravel's store() method generates a unique filename by default, but it doesn’t always preserve the original extension reliably. Instead, use storeAs() to explicitly define a filename that includes the original .docx extension. We’ll also store the original filename in your database so you can use it for downloads later.
First, add a new column to your applications table to save the original resume name:
php artisan make:migration add_resume_original_name_to_applications_table --table=applications
In the migration file:
public function up() { Schema::table('applications', function (Blueprint $table) { $table->string('resume_original_name')->nullable(); }); } public function down() { Schema::table('applications', function (Blueprint $table) { $table->dropColumn('resume_original_name'); }); }
Run the migration:
php artisan migrate
Now update your create() method in ApplicationController.php:
function create(Request $req) { $application = new Application; $application->opening_id = $req->input('opening_id'); $application->first_name = $req->input('first_name'); $application->last_name = $req->input('last_name'); $application->gender = $req->input('gender'); $application->dob = $req->input('dob'); $application->address = $req->input('address'); $application->mobile = $req->input('mobile'); $application->email = $req->input('email'); // Handle resume upload properly $resumeFile = $req->file('resume'); // Generate a unique filename while keeping original extension $uniqueFilename = uniqid() . '.' . $resumeFile->getClientOriginalExtension(); // Store the file in public/resumes $path = $resumeFile->storeAs('public/resumes', $uniqueFilename); // Save relative path (without public/) and original filename $application->resume = str_replace('public/', '', $path); $application->resume_original_name = $resumeFile->getClientOriginalName(); $application->application_status = $req->input('application_status'); $application->save(); return redirect('admin/view-applications'); }
This ensures your uploaded .docx files are stored with the correct extension instead of being labeled as .file.
Step 2: Add a Download Route & Method
To let users download the file in its original .docx format, create a dedicated route and controller method that sets the correct HTTP headers.
Add this route to web.php:
use App\Http\Controllers\ApplicationController; use App\Models\Application; Route::get('/admin/download-resume/{application}', [ApplicationController::class, 'downloadResume']) ->name('download.resume');
Add the downloadResume() method to ApplicationController.php:
public function downloadResume(Application $application) { // Get the full path to the stored file $filePath = storage_path('app/public/' . $application->resume); // Check if the file exists if (!file_exists($filePath)) { abort(404, 'Resume not found'); } // Send the file as a download with original name and correct MIME type return response()->download( $filePath, $application->resume_original_name, [ 'Content-Type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', ] ); }
Step 3: Add Download Link in Your View
In your view where you list applications, add a link to trigger the download:
<a href="{{ route('download.resume', $application) }}" class="btn btn-primary"> Download Resume </a>
Why This Works:
- Storing with Extension: Using
storeAs()ensures the file retains its .docx extension, so your OS doesn’t label it as.file. - Original Filename: Saving the original name in the database lets users download the file with the same name they uploaded.
- Correct Headers: Setting the
Content-Typeheader tells the browser this is a Word document, so it will handle it correctly (e.g., open in Word or save as .docx).
内容的提问来源于stack exchange,提问作者Vinith Maniv

