Files
2026-04-28 21:14:25 +03:00

281 lines
8.1 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Excel dosyasını PDF'e dönüştüren fonksiyon
*
* @param string $xlsx Excel dosyasının tam yolu
* @param string $pdf_dir PDF çıktısının kaydedileceği dizin
* @param array $options Ek seçenekler (timeout, log_level vb.)
* @return array Dönüşüm sonucu bilgileri
* @throws Exception Hata durumunda
*/
function xlsx_to_pdf($xlsx, $pdf_dir, $options = []) {
// PDF cache bypass: Dizin içerisinde mevcut aynı isimli PDF varsa siliyoruz ve tekrardan oluşturacak
$pdf_output_path = rtrim($pdf_dir, '/\\') . DIRECTORY_SEPARATOR . basename(pathinfo($xlsx, PATHINFO_FILENAME)) . '.pdf';
if (file_exists($pdf_output_path)) {
@unlink($pdf_output_path);
}
// Varsayılan seçenekler
$defaults = [
'timeout' => 300, // 5 dakika timeout
'log_level' => 'info',
'create_backup' => true,
'validate_input' => true,
'cleanup_temp' => true
];
$options = array_merge($defaults, $options);
try {
// Giriş parametrelerini doğrula
if ($options['validate_input']) {
validate_xlsx_to_pdf_inputs($xlsx, $pdf_dir);
}
// Çıktı dizinini oluştur
create_output_directory($pdf_dir);
// LibreOffice komutunu hazırla
$command = build_libreoffice_command($xlsx, $pdf_dir);
// Komutu çalıştır
$result = execute_conversion_command($command, $options['timeout']);
// Sonucu işle
$output = process_conversion_output($result);
// Başarı logu
log_conversion_success($xlsx, $pdf_dir, $output);
return [
'success' => true,
'output_file' => $output,
'message' => 'Dönüşüm başarıyla tamamlandı',
'timestamp' => date('Y-m-d H:i:s')
];
} catch (Exception $e) {
// Hata logu
log_conversion_error($xlsx, $pdf_dir, $e->getMessage());
return [
'success' => false,
'error' => $e->getMessage(),
'timestamp' => date('Y-m-d H:i:s')
];
}
}
/**
* Giriş parametrelerini doğrular
*/
function validate_xlsx_to_pdf_inputs($xlsx, $pdf_dir) {
// Excel dosyasının varlığını kontrol et
if (!file_exists($xlsx)) {
throw new Exception("Excel dosyası bulunamadı: {$xlsx}");
}
// Excel dosyasının okunabilir olduğunu kontrol et
if (!is_readable($xlsx)) {
throw new Exception("Excel dosyası okunamıyor: {$xlsx}");
}
// Dosya uzantısını kontrol et
$extension = strtolower(pathinfo($xlsx, PATHINFO_EXTENSION));
if (!in_array($extension, ['xlsx', 'xls'])) {
throw new Exception("Geçersiz dosya formatı. Sadece .xlsx ve .xls dosyaları desteklenir.");
}
// PDF dizininin yazılabilir olduğunu kontrol et
if (file_exists($pdf_dir) && !is_writable($pdf_dir)) {
throw new Exception("PDF çıktı dizini yazılabilir değil: {$pdf_dir}");
}
}
/**
* Çıktı dizinini oluşturur
*/
function create_output_directory($pdf_dir) {
if (!is_dir($pdf_dir)) {
if (!mkdir($pdf_dir, 0755, true)) {
throw new Exception("PDF çıktı dizini oluşturulamadı: {$pdf_dir}");
}
}
}
/**
* LibreOffice komutunu oluşturur
*/
function build_libreoffice_command($xlsx, $pdf_dir) {
// Güvenli komut oluşturma
$xlsx_escaped = escapeshellarg($xlsx);
$pdf_dir_escaped = escapeshellarg($pdf_dir);
// LibreOffice komutunu oluştur (environment variable'ları export ile set et)
$command = sprintf(
'export LANG=en_US.UTF-8 && sudo -u root libreoffice --headless --convert-to pdf --outdir %s %s 2>&1',
$pdf_dir_escaped,
$xlsx_escaped
);
return $command;
}
/**
* Dönüşüm komutunu çalıştırır
*/
function execute_conversion_command($command, $timeout) {
// Basit shell_exec kullanarak komutu çalıştır (proc_open ile environment variable sorunu var)
$output = shell_exec($command);
// Hata kontrolü - shell_exec null dönerse komut çalışmamış demektir
if ($output === null) {
throw new Exception("LibreOffice komutu çalıştırılamadı. Komut: " . $command);
}
// LibreOffice çıktısında hata var mı kontrol et
if (strpos($output, 'Error') !== false || strpos($output, 'error') !== false) {
throw new Exception("LibreOffice dönüşüm hatası: " . trim($output));
}
// Çıktı boş mu kontrol et
if (empty(trim($output))) {
throw new Exception("LibreOffice çıktısı boş. Komut başarısız olmuş olabilir.");
}
return $output;
}
/**
* Dönüşüm çıktısını işler
*/
function process_conversion_output($shell_output) {
// Çıktıyı temizle
$output = extract_between_markers_pdf($shell_output);
if (is_null($output)) {
$output = trim($shell_output);
}
return $output;
}
/**
* Başarılı dönüşüm logu
*/
function log_conversion_success($xlsx, $pdf_dir, $output) {
$log_message = sprintf(
"[SUCCESS] Excel to PDF conversion completed - File: %s, Output: %s, Result: %s",
$xlsx,
$pdf_dir,
$output
);
error_log($log_message);
}
/**
* Dönüşüm hatası logu
*/
function log_conversion_error($xlsx, $pdf_dir, $error_message) {
$log_message = sprintf(
"[ERROR] Excel to PDF conversion failed - File: %s, Output: %s, Error: %s",
$xlsx,
$pdf_dir,
$error_message
);
error_log($log_message);
}
/**
* PDF marker'ları arasındaki içeriği çıkarır
*
* @param string $input_str LibreOffice çıktısı
* @return string|null Çıkarılan içeriği veya null
*/
function extract_between_markers_pdf($input_str) {
// PDF export marker'ları arasındaki içeriği bul
// Excel dosyaları Writer olarak algılanabilir, bu yüzden her iki filter'ı da kontrol et
$patterns = [
'/->\s*(.*?)\s*using filter : calc_pdf_Export/', // Calc (spreadsheet) için
'/->\s*(.*?)\s*using filter : writer_pdf_Export/', // Writer (document) için
'/convert\s+(.*?)\s+as\s+a\s+(.*?)\s+->\s+(.*?)\s+using filter : (.*?)_Export/' // Genel pattern
];
foreach ($patterns as $pattern) {
if (preg_match($pattern, $input_str, $matches)) {
// İlk pattern için dosya yolu, ikinci için de dosya yolu, üçüncü için tam çıktı
if (count($patterns) === 3 && $pattern === $patterns[2]) {
return trim($matches[3]); // PDF dosya yolu
}
return trim($matches[1]); // Dosya yolu
}
}
return null;
}
/**
* Eski fonksiyon için geriye uyumluluk
* @deprecated Bu fonksiyon artık kullanılmamalı, xlsx_to_pdf() kullanın
*/
function xlsx_to_pdf_legacy($xlsx, $pdf_dir) {
trigger_error(
'xlsx_to_pdf_legacy() fonksiyonu deprecated. xlsx_to_pdf() kullanın.',
E_USER_DEPRECATED
);
$result = xlsx_to_pdf($xlsx, $pdf_dir);
if ($result['success']) {
return $result['output_file'];
}
return $result['error'];
}
function xlsx_to_pdf2($xlsx, $pdf_dir) {
// Ensure the LANG environment variable is set
putenv('LANG=ru_RU.UTF-8');
// Ensure the output directory exists
if (!is_dir($pdf_dir)) {
mkdir($pdf_dir, 0777, true);
}
// Construct the command
$command = "sudo -u root libreoffice --headless --convert-to pdf --outdir '" . ($pdf_dir) . "' '" . ($xlsx) . "' ";
// Execute the command
$shellOutput = shell_exec("$command 2>&1");
$output = extract_between_markers_pdf($shellOutput);
if(is_null($output)) {
$output = $shellOutput;
}
return $output;
}
function extract_between_markers_pdf2($input_str) {
// Define the regular expression pattern to match the content between the markers
$pattern = '/->\s*(.*?)\s*using filter : calc_pdf_Export/';
// Perform the regex match
if (preg_match($pattern, $input_str, $matches)) {
// Return the matched content
return $matches[1];
}
// Return null if no match is found
return null;
}