首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

跨平台 MySQL 導出 Excel 工具:Perl + Spreadsheet::WriteExcel::Big 實現大文件生成

     編輯:MySQL 資料庫相關知識

需在 Linux 服務器無圖形界面環境下將 MySQL 查詢結果導出為 Excel (.xls) 文件供業務下載分析。本工具基於 Perl DBI + Spreadsheet::WriteExcel::Big 實現,支持命令行參數化、大文件流式寫入、Unicode 編碼處理,無需 Windows/Office 環境。

依賴模塊安裝

# CPAN 安裝
cpan DBI DBD::mysql Unicode::Map Spreadsheet::WriteExcel::Big

# 或系統包管理器
apt-get install libdbi-perl libdbd-mysql-perl libunicode-map-perl libspreadsheet-writeexcel-perl
# 注意:WriteExcel::Big 可能需從 CPAN 獲取最新版

核心腳本:mysql2excel.pl

#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use Unicode::Map;
use Spreadsheet::WriteExcel::Big;  # 支持 > 65536 行、大文件

# ===== 配置區 =====
my $hostname = '192.168.1.133';
my $username = 'user';
my $password = 'pass';
my $dbname   = 'db';
my $trans_compress = 1;  # 1=啟用壓縮協議

# Excel 列字母映射(支持超出 Z 列)
my @cols = ('A:A','B:B','C:C','D:D','E:E','F:F','G:G','H:H','I:I','J:J',
            'K:K','L:L','M:M','N:N','O:O','P:P','Q:Q','R:R','S:S','T:T',
            'U:U','V:V','W:W','X:X','Y:Y','Z:Z',
            'AA:AA','BB:BB','CC:CC','DD:DD','EE:EE','FF:FF','GG:GG','HH:HH',
            'II:II','JJ:JJ','KK:KK','LL:LL','MM:MM','NN:NN','OO:OO','PP:PP',
            'QQ:QQ','RR:RR','SS:SS','TT:TT','UU:UU','VV:VV','WW:WW','XX:XX',
            'YY:YY','ZZ:ZZ');
# ====================

$| = 1;  # 刷新輸出緩衝

# 參數解析:mysql2excel.pl "output.xls" "SELECT * FROM table WHERE ..."
die "Usage: $0  \"SELECT ...\"\n" unless @ARGV == 2;
my ($outFile, $sql) = @ARGV;
$sql =~ s/^\"|\"$//g;  # 去除包裹雙引號

warn "MySQL to Excel\nby Perl Script\n=====================\nSQL: $sql\n";

# 數據庫連接
my $dsn = "DBI:mysql:database=$dbname;host=$hostname;mysql_compression=$trans_compress";
my $dbh = DBI->connect($dsn, $username, $password, { RaiseError => 1, PrintError => 0, AutoCommit => 1 })
    or die "Connect failed: $DBI::errstr";

my $sth = $dbh->prepare($sql) or die "Prepare failed: $dbh->errstr";
my $rows = $sth->execute() or die "Execute failed: $sth->errstr";
warn "Rows fetched: $rows\n";

# 列名獲取
my $colNames = $sth->{NAME};
my $colCount = @$colNames;
die "Columns ($colCount) exceed max supported (" . scalar(@cols) . ")\n" if $colCount > @cols;

# 創建 Excel 工作簿
my $workbook = Spreadsheet::WriteExcel::Big->new($outFile)
    or die "Create workbook failed: $!";
my $worksheet = $workbook->add_worksheet('Data');

# 寫入表頭
my $headerFormat = $workbook->add_format(bold => 1, bgcolor => '#4472C4', color => 'white', border => 1);
for my $i (0 .. $colCount-1) {
    $worksheet->write(0, $i, $colNames->[$i], $headerFormat);
}

# 流式寫入數據行
my $rowNum = 1;
my $dataFormat = $workbook->add_format(border => 1);
while (my $rowRef = $sth->fetchrow_arrayref) {
    for my $i (0 .. $colCount-1) {
        my $val = $rowRef->[$i];
        # Unicode 處理:DBI 返回 UTF-8,WriteExcel 內部處理
        $worksheet->write($rowNum, $i, $val // '', $dataFormat);
    }
    $rowNum++;
    # 進度提示
    warn "Written $rowNum rows...\n" if $rowNum % 10000 == 0;
}

$workbook->close();
warn "Export completed: $rowNum rows written to $outFile\n";

$dbh->disconnect();

使用示例

# 導出全表
perl mysql2excel.pl "orders_2024.xls" "SELECT * FROM orders WHERE YEAR(created_at)=2024"

# 導出多表 JOIN 結果
perl mysql2excel.pl "customer_summary.xls" "
    SELECT c.id, c.name, COUNT(o.id) AS order_count, SUM(o.amount) AS total_amount
    FROM customers c
    LEFT JOIN orders o ON c.id = o.customer_id
    GROUP BY c.id, c.name
    HAVING total_amount > 10000
"

關鍵技術點解析

現代替代方案對比

挑戰解決方案
大文件內存溢出Spreadsheet::WriteExcel::Big 使用臨時文件存儲 XML 部分,內存佔用恆定,支持百萬行。
中文亂碼DBI mysql_enable_utf8 => 1(新版默認開啟)+ WriteExcel 內部 UTF-16LE 編碼,無需手動轉碼。
列數超出 256 (BIFF8 限制)WriteExcel::Big 基於 Office Open XML (OOXML) 實現,突破 256 列/65536 行限制,生成 .xlsx 兼容格式(雖副檔名 .xls)。
長時間運行進度不可見每 10000 行 warn 輸出進度,配合 tail -f 監控。
SQL 注入風險腳本直接執行參數 SQL,屬信任內部工具;對外暴露需加參數化驗證層。

總結

Perl + Spreadsheet::WriteExcel::Big 為「Linux 無界面導出大 Excel」提供了經典可靠方案。隨著 Python 生態成熟,pandas.ExcelWriter(engine='openpyxl', mode='w') 配合 chunksize 分塊寫入已成主流選擇。選型原則:存量 Perl 系統續用、新建項目首選 Python、Web 服務化用 Node.js、純數據遷移用 mysqldump。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
工具語言優點缺點適用場景
本 Perl 腳本Perl輕量、無依賴 Office、Linux 原生、流式寫入需 Perl 環境、維護成本、.xls 格式兼容性有限定時任務、嵌入式導出、舊系統集成
Python + openpyxl/pandasPython生態豐富、DataFrame 操作強、原生 .xlsx大文件內存壓力大(需分塊寫入)數據分析、報表自動化、現代技術棧
Node.js + exceljsJavaScript異步流式、Web 服務集成易大文件性能一般API 導出端點、前端觸發下載
mysqldump + csvkitShell無代碼、標準工具鏈、極快無格式控制、純 CSV純數據遷移、不需樣式