You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
3.9 KiB
Python
116 lines
3.9 KiB
Python
import os
|
|
import subprocess
|
|
import platform
|
|
from pathlib import Path
|
|
import shutil
|
|
|
|
from loguru import logger
|
|
|
|
|
|
class ConvertToPdfError(Exception):
|
|
def __init__(self, msg):
|
|
self.msg = msg
|
|
super().__init__(self.msg)
|
|
|
|
|
|
def check_fonts_installed():
|
|
"""Check if required Chinese fonts are installed."""
|
|
system_type = platform.system()
|
|
|
|
if system_type in ['Windows', 'Darwin']:
|
|
pass
|
|
else:
|
|
# Linux: use fc-list
|
|
try:
|
|
output = subprocess.check_output(['fc-list', ':lang=zh'], encoding='utf-8')
|
|
if output.strip(): # 只要有任何输出(非空)
|
|
return True
|
|
else:
|
|
logger.warning(
|
|
f"No Chinese fonts were detected, the converted document may not display Chinese content properly."
|
|
)
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def get_soffice_command():
|
|
"""Return the path to LibreOffice's soffice executable depending on the platform."""
|
|
system_type = platform.system()
|
|
|
|
# First check if soffice is in PATH
|
|
soffice_path = shutil.which('soffice')
|
|
if soffice_path:
|
|
return soffice_path
|
|
|
|
if system_type == 'Windows':
|
|
# Check common installation paths
|
|
possible_paths = [
|
|
Path(os.environ.get('PROGRAMFILES', 'C:/Program Files')) / 'LibreOffice/program/soffice.exe',
|
|
Path(os.environ.get('PROGRAMFILES(X86)', 'C:/Program Files (x86)')) / 'LibreOffice/program/soffice.exe',
|
|
Path('C:/Program Files/LibreOffice/program/soffice.exe'),
|
|
Path('C:/Program Files (x86)/LibreOffice/program/soffice.exe')
|
|
]
|
|
|
|
# Check other drives for windows
|
|
for drive in ['C:', 'D:', 'E:', 'F:', 'G:', 'H:']:
|
|
possible_paths.append(Path(f"{drive}/LibreOffice/program/soffice.exe"))
|
|
|
|
for path in possible_paths:
|
|
if path.exists():
|
|
return str(path)
|
|
|
|
raise ConvertToPdfError(
|
|
"LibreOffice not found. Please install LibreOffice from https://www.libreoffice.org/ "
|
|
"or ensure soffice.exe is in your PATH environment variable."
|
|
)
|
|
else:
|
|
# For Linux/macOS, provide installation instructions if not found
|
|
try:
|
|
# Try to find soffice in standard locations
|
|
possible_paths = [
|
|
'/usr/bin/soffice',
|
|
'/usr/local/bin/soffice',
|
|
'/opt/libreoffice/program/soffice',
|
|
'/Applications/LibreOffice.app/Contents/MacOS/soffice'
|
|
]
|
|
for path in possible_paths:
|
|
if os.path.exists(path):
|
|
return path
|
|
|
|
raise ConvertToPdfError(
|
|
"LibreOffice not found. Please install it:\n"
|
|
" - Ubuntu/Debian: sudo apt-get install libreoffice\n"
|
|
" - CentOS/RHEL: sudo yum install libreoffice\n"
|
|
" - macOS: brew install libreoffice or download from https://www.libreoffice.org/\n"
|
|
" - Or ensure soffice is in your PATH environment variable."
|
|
)
|
|
except Exception as e:
|
|
raise ConvertToPdfError(f"Error locating LibreOffice: {str(e)}")
|
|
|
|
|
|
def convert_file_to_pdf(input_path, output_dir):
|
|
"""Convert a single document (ppt, doc, etc.) to PDF."""
|
|
if not os.path.isfile(input_path):
|
|
raise FileNotFoundError(f"The input file {input_path} does not exist.")
|
|
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
check_fonts_installed()
|
|
|
|
soffice_cmd = get_soffice_command()
|
|
|
|
cmd = [
|
|
soffice_cmd,
|
|
'--headless',
|
|
'--norestore',
|
|
'--invisible',
|
|
'--convert-to', 'pdf',
|
|
'--outdir', str(output_dir),
|
|
str(input_path)
|
|
]
|
|
|
|
process = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
if process.returncode != 0:
|
|
raise ConvertToPdfError(f"LibreOffice convert failed: {process.stderr.decode()}")
|