PHP将指定文件夹下多csv文件[即多表]导入到sqlite单文件

支持多表,中文字段,csv文件utf-8编码 逗号分隔,第一行字段以后一行一条内容

php 复制代码
<?php

class CsvToSqlite {
    private $db;
    private $csvDir;
    private $sqliteFile;
    public function __construct($csvDir, $sqliteFile) {
        $this->csvDir = rtrim($csvDir, '/');
        $this->sqliteFile = $sqliteFile;
        try {
            $this->db = new PDO("sqlite:{$this->sqliteFile}");
            $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            die("数据库连接失败: " . $e->getMessage());
        }
    }
    public function convert() {
        $csvFiles = glob($this->csvDir . '/*.csv');        
        foreach ($csvFiles as $csvFile) {
            $this->processCsvFile($csvFile);
        }        
        echo "所有CSV文件处理完成!\n";
    }
    private function processCsvFile($csvFile) {
        $tableName = pathinfo($csvFile, PATHINFO_FILENAME);
        echo "正在处理文件: {$csvFile}\n";        
        try {
            $handle = fopen($csvFile, 'r');
            if ($handle === false) throw new Exception("无法打开文件: {$csvFile}");
            $headers = fgetcsv($handle);
            if ($headers === false) throw new Exception("CSV文件为空: {$csvFile}");
            $this->createTable($tableName, $headers);
            $placeholders = str_repeat('?,', count($headers) - 1) . '?';
            $sql = "INSERT INTO {$tableName} VALUES ($placeholders)";
            $stmt = $this->db->prepare($sql);
            $this->db->beginTransaction();
            while (($row = fgetcsv($handle)) !== false) {
                if (count($row) === count($headers)) {
                    try {
                        $stmt->execute($row);
                    } catch (PDOException $e) {
                        echo "插入数据失败: " . $e->getMessage() . "\n";
                        continue;
                    }
                }
            }
            $this->db->commit();            
            fclose($handle);
            echo "表 {$tableName} 创建并导入完成\n";            
        } catch (Exception $e) {
            if ($this->db->inTransaction()) {
                $this->db->rollBack();
            }
            echo "处理文件 {$csvFile} 时出错: " . $e->getMessage() . "\n";
        }
    }
    private function createTable($tableName, $headers) {
        $tableName = $this->sanitizeIdentifier($tableName);
        $columns = array_map([$this, 'sanitizeIdentifier'], $headers);
        $columnDefs = array_map(function($col) {
            return "{$col} TEXT";
        }, $columns);        
        $sql = "CREATE TABLE IF NOT EXISTS {$tableName} (" . 
               implode(', ', $columnDefs) . ")";        
        try {
            $this->db->exec($sql);
            $this->db->exec("DELETE FROM {$tableName}");
        } catch (PDOException $e) {
            throw new Exception("创建表失败: $sql@" . $e->getMessage());
        }
    }
    private function sanitizeIdentifier($identifier) {
        $safe = preg_replace('/[^\w\x{4e00}-\x{9fa5}]+/u', '_', $identifier);
        if (is_numeric($safe[0])) { $safe = 'col_' . $safe;}
        return Trim($safe,"_");
    }
    public function getTableRowCount($tableName) {
        $tableName = $this->sanitizeIdentifier($tableName);
        $stmt = $this->db->query("SELECT COUNT(*) FROM {$tableName}");
        return $stmt->fetchColumn();
    }
    public function __destruct() {
        $this->db = null;
    }
}

// 使用示例
try {
    $csvDir = './csv_files';
    $sqliteFile = './database.sqlite';    
    $converter = new CsvToSqlite($csvDir, $sqliteFile);    
    $converter->convert();    
} catch (Exception $e) {
    echo "发生错误: " . $e->getMessage() . "\n";
}
?>
相关推荐
JavaNice哥3 小时前
1初识别jvm
jvm
涛粒子3 小时前
JVM垃圾回收详解
jvm
逊嘘3 小时前
【Java语言】抽象类与接口
java·开发语言·jvm
龙哥·三年风水12 小时前
群控系统服务端开发模式-应用开发-个人资料
分布式·php·群控系统
鱼跃鹰飞13 小时前
大厂面试真题-简单说说线程池接到新任务之后的操作流程
java·jvm·面试
王佑辉13 小时前
【jvm】Major GC
jvm
阿维的博客日记13 小时前
jvm学习笔记-轻量级锁内存模型
jvm·cas·轻量级锁
Dingww101116 小时前
梧桐数据库中的网络地址类型使用介绍分享
数据库·oracle·php
曹申阳17 小时前
2. JVM的架构模型和生命周期
jvm·架构