Django 2.1.7调用LibreOffice转换Doc为Txt遇FileNotFoundError求助
Fixing LibreOffice Conversion Error in Django File Upload API
Let's break down why your code is throwing that FileNotFoundError and fix it step by step:
Root Causes of the Error
- Malformed Command String: Your concatenation of command parts is missing spaces, creating an invalid string like
libreoffice --headless --convert-totxt:Text (encoded):UTF8test.doc. Subprocess tries to execute this entire string as a single non-existent executable, hence the error. - Incorrect Subprocess Usage: Passing a single string to
subprocess.call()withoutshell=Truetells Python to look for an executable with that full string as its name—this isn’t what you want. Using a list of arguments is safer and avoids this issue. - Hardcoded Filename: You’re using
test.docinstead of the actual uploaded filename, so even if the command worked, it wouldn’t target the right file. - Relative Path Issue: Using
media/as the path might fail because LibreOffice may not run in the same working directory as your Django app.
Corrected Code
Here's the fixed API view with proper error handling and correct subprocess usage:
import os import subprocess from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework import status from django.core.files.storage import FileSystemStorage @api_view(['POST']) def convertfiledoc(request): try: # Retrieve uploaded file from request file = request.FILES['file'] fs = FileSystemStorage() # Save file to media directory and get its filename filename = fs.save(file.name, file) # Get full absolute path to the uploaded file full_file_path = fs.path(filename) # Build LibreOffice command as a list of arguments (safer than shell=True) cmd = [ 'libreoffice', '--headless', '--convert-to', 'txt:Text (encoded):UTF8', full_file_path ] # Execute conversion command exit_code = subprocess.call(cmd) if exit_code == 0: # Generate converted TXT filename txt_filename = os.path.splitext(filename)[0] + '.txt' # Get URL to access the converted file txt_file_url = fs.url(txt_filename) return Response( data={"message": "Conversion successful", "txt_file_url": txt_file_url}, status=status.HTTP_200_OK ) else: return Response( data={"message": f"Conversion failed with exit code {exit_code}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR ) # Handle missing file in request except KeyError: return Response( data={"message": "Please upload a file using the 'file' key"}, status=status.HTTP_400_BAD_REQUEST ) # Catch unexpected errors except Exception as e: return Response( data={"message": f"An error occurred: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR )
Additional Checks to Ensure Success
- Install Required LibreOffice Packages:
On your Ubuntu 18.04 server, run these commands to get headless support and DOC file handling:sudo apt update sudo apt install libreoffice-headless libreoffice-writer - Verify LibreOffice Path:
If you still get a "not found" error, runwhich libreofficeto get the absolute path (usually/usr/bin/libreoffice) and replace'libreoffice'in thecmdlist with this full path. - Check Permissions:
Ensure the user running your Django server (e.g.,www-datafor Apache) has read/write access to the media directory. - Validate File Types:
Add a check to confirm the uploaded file is a DOC/DOCX file before processing to avoid unnecessary errors.
内容的提问来源于stack exchange,提问作者johnny68




