format('d.m.Y'); $timeStr = $currentDateTime->format('H.i'); $fileName = $projectNumber . '_' . $moduleFileName . '_' . $dateStr . '_' . $timeStr; // Kayıt yapılacak dosya yolu $csvPath = storage_path($fileName . '.csv'); @unlink($csvPath); // MySQL komutunu tanımlayın (sudo olmadan) $query = "SELECT $columns FROM $tableName" . $whereClause; // İsteğe bağlı olarak çok büyük veri setlerinde LIMIT eklemek isteyebilirsiniz // Kullanıcı arayüzünden bir limit parametresi alabilir veya varsayılan bir limit belirleyebilirsiniz $limit = get("limit", 0); // Varsayılan olarak 0 (tüm veriyi getirir) if ($limit > 0) { $query .= " LIMIT $limit"; } $query .= ";"; // CSV dosyasını başlat file_put_contents($csvPath, "\xEF\xBB\xBF"); // UTF-8 BOM // Excel uyumluluğu için tüm alanları tırnak içine al $excelCompatible = true; // Doğrudan mysql komutunu çalıştırarak sonuçları CSV formatında alacağız $mysqlCmd = "/usr/bin/mysql -u " . escapeshellarg($user) . " -p" . escapeshellarg($password) . " -D " . escapeshellarg($database) . " --default-character-set=utf8mb4" . " -B" . // Batch mode (tab-separated) " -N" . // No column names " -e " . escapeshellarg("SET NAMES utf8mb4; $query") . " 2>/dev/null"; // mysql komutunu çalıştır ve sonuçları satır satır oku $mysqlHandle = popen($mysqlCmd, 'r'); // Sütun adlarını ayarlamak için işlem yapalım $csvHeaderColumns = []; if(!getesit("columns", "")) { // Özel sütun seçimi varsa, bu sütunların adlarını kullan $headerColumnsArr = explode(',', base64_decode(get("columns"))); // Sütun adlarını temizle (COALESCE ifadelerini kaldır) foreach($headerColumnsArr as $colName) { $colName = trim($colName); // COALESCE(`column`, '') column formatındaysa, sadece column kısmını al if(preg_match('/^.*`([^`]+)`.*$/', $colName, $matches)) { $csvHeaderColumns[] = $matches[1]; } else { // Değilse doğrudan ismi kullan $csvHeaderColumns[] = $colName; } } } else { // Tüm sütunları kullanıyorsa, veritabanından al $tableInfoCmd = "/usr/bin/mysql -u " . escapeshellarg($user) . " -p" . escapeshellarg($password) . " -D " . escapeshellarg($database) . " --default-character-set=utf8mb4" . " -e " . escapeshellarg("SHOW COLUMNS FROM $tableName") . " 2>/dev/null"; // Sütun adlarını al exec($tableInfoCmd, $columnInfoOutput); // İlk satırı atla (başlık satırı) for ($i = 1; $i < count($columnInfoOutput); $i++) { $parts = preg_split('/\s+/', trim($columnInfoOutput[$i]), 2); if (!empty($parts[0])) { $csvHeaderColumns[] = $parts[0]; } } } // Sütun adlarını CSV dosyasına yaz if (!empty($csvHeaderColumns)) { // CSV formatında tırnak kullanarak başlık satırını oluştur // fputcsv ile güvenli CSV header yazma (otomatik escaping) $csvFile = fopen($csvPath, 'a'); fputcsv($csvFile, $csvHeaderColumns, $delimiter, '"'); fclose($csvFile); } // Verileri satır satır oku ve dosyaya yaz while (($line = fgets($mysqlHandle)) !== false) { // Satırın sonundaki satır sonu karakterini kaldır $line = rtrim($line); // Satırı tab karakterlerine göre böl $fields = explode("\t", $line); // Tarih formatlarını düzelt ve decimal alanları virgüllü yap foreach ($fields as $i => &$field) { // Eğer bu alan forceStringFields içindeyse, değeri ="değer" olarak yaz if (isset($csvHeaderColumns[$i]) && in_array($csvHeaderColumns[$i], $forceStringFields)) { $field = '="' . str_replace('"', '""', $field) . '"'; } // Eğer bu alan forceVirgulFields içindeyse, decimal değerleri virgüllü yap elseif (isset($csvHeaderColumns[$i]) && in_array($csvHeaderColumns[$i], $forceVirgulFields)) { if (!empty($field) && is_numeric($field) && strpos($field, '.') !== false) { $field = str_replace('.', ',', $field); } } else { // Tarih formatını değiştir $field = preg_replace_callback( '/^(\d{4})-(\d{2})-(\d{2})$/', function ($matches) { return $matches[3] . '.' . $matches[2] . '.' . $matches[1]; // dd.mm.yyyy formatına }, $field ); } } $fields = str_replace("\\\\", "\\", $fields); // fputcsv ile güvenli CSV yazma (otomatik escaping - sütun kaymasını önler) $csvFile = fopen($csvPath, 'a'); fputcsv($csvFile, $fields, $delimiter, '"'); fclose($csvFile); } // mysql process'i kapat pclose($mysqlHandle); $fileType = "csv"; if(getesit("file_type", "xlsx")) { // XLSX dönüşümü öncesi belleği temizle gc_collect_cycles(); try { // LibreOffice ile CSV'den XLSX'e dönüştürme $outputDir = storage_path(); $outputFilename = "$fileName.xlsx"; // LibreOffice için filtreleme seçenekleri: // 9 = Tab karakteri ayırıcı olarak kullanıldığını belirt // 0 = Metin sınırlayıcı karakteri kullanılmadığını belirt (veya ihtiyaca göre değiştirilebilir) // 76 = Karakter seti (UTF-8) // 1 = İlk satır başlık $shellCmd = "libreoffice --headless --infilter=\"Text - txt - csv (StarCalc):9,0,76,1\" --convert-to xlsx --outdir " . escapeshellarg($outputDir) . " " . escapeshellarg($csvPath) . " 2>&1"; // Komutu çalıştır $output = []; $returnCode = 0; exec($shellCmd, $output, $returnCode); // Hata kontrolü if ($returnCode !== 0) { throw new Exception("LibreOffice conversion failed: " . implode("\n", $output)); } // LibreOffice dönüştürme işlemi tamamlandıktan sonra, dosyanın doğru adını bulalım $csvBaseName = basename($csvPath); $csvFileNameWithoutExt = pathinfo($csvBaseName, PATHINFO_FILENAME); $expectedXlsxPath = $outputDir . '/' . $csvFileNameWithoutExt . '.xlsx'; // Eğer beklenen dosya yoksa, orijinal dosya adıyla tekrar deneyelim if (!file_exists($expectedXlsxPath)) { $expectedXlsxPath = $outputDir . '/' . $fileName . '.xlsx'; } // Son dosya yolunu saklayalım $xlsxOutputPath = $expectedXlsxPath; $fileType = "xlsx"; } catch (Exception $e) { // XLSX dönüşümü başarısız olursa, CSV dosyasını sunalım $xlsxResult = ['error' => $e->getMessage()]; $fileType = "csv"; } } // CSV dosyasını kontrol et - çok büyükse bile LibreOffice ile dönüştürmeyi dene $fileSize = filesize($csvPath); $maxSize = 100 * 1024 * 1024; // 100MB - LibreOffice daha büyük dosyaları işleyebilir // Çok büyük dosyalar için uyarı logla ama yine de dönüştürmeyi dene if ($fileSize > $maxSize && $fileType == "xlsx") { // Büyük dosya işleme durumunu loglayabilirsiniz error_log("Warning: Processing large file ($fileName.csv) of size " . round($fileSize / (1024 * 1024), 2) . " MB"); } if(isset($xlsxResult['error'])) { // Hata durumunda CSV dosyasını sun error_log("XLSX conversion error: " . $xlsxResult['error']); yonlendir(url("storage/$fileName.csv")); } else { if ($fileType == "xlsx") { // Dosya adından storage path kısmını çıkar, sadece relatif yolu ve dosya adını al $relativePath = str_replace(storage_path(), '', $xlsxOutputPath); // Başındaki slash'ı kaldır $relativePath = ltrim($relativePath, '/'); yonlendir(url("storage/$relativePath")); } else { yonlendir(url("storage/$fileName.$fileType")); } } // İşlem tamamlandıktan sonra belleği temizle gc_collect_cycles(); // Geçici dosyaları temizle if ($fileType == "xlsx" && file_exists($csvPath)) { @unlink($csvPath); // XLSX oluşturulduysa CSV'yi silebiliriz } ?>