首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

將資料表匯出為真正的 Excel 檔案並包含欄位名稱

     編輯:關於SqlServer

功能簡介

提供一個預存程序 p_exporttb,可將指定資料表或檢視表的資料匯出為真正的 Excel 檔案,自動包含欄位名稱作為標題列。若檔案不存在則自動建立,若工作表不存在亦自動建立。僅支援標準資料類型,確保相容性。

預存程式完整碼

IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[p_exporttb]') AND OBJECTPROPERTY(id, N'IsProcedure') = 1)
    DROP PROCEDURE [dbo].[p_exporttb];
GO

CREATE PROCEDURE p_exporttb
    @tbname   SYSNAME,          -- 要匯出的資料表/檢視表名稱
    @path     NVARCHAR(1000),   -- 檔案儲存目錄
    @fname    NVARCHAR(250) = '' -- 檔案名稱,預設為 資料表名.xls
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @err        INT,
            @src        NVARCHAR(255),
            @desc       NVARCHAR(255),
            @out        INT,
            @obj        INT,
            @constr     NVARCHAR(1000),
            @sql        VARCHAR(8000),
            @fdlist     VARCHAR(8000);

    -- 參數預設處理
    IF ISNULL(@fname, '') = ''
        SET @fname = @tbname + '.xls';

    -- 確保路徑以反斜線結尾
    IF RIGHT(@path, 1) <> '\'
        SET @path = @path + '\';

    SET @sql = @path + @fname;

    -- 檢查檔案是否存在
    CREATE TABLE #tb (a BIT, b BIT, c BIT);
    INSERT INTO #tb EXEC master..xp_fileexist @sql;

    -- 根據檔案是否存在建立不同連接字串
    IF EXISTS (SELECT 1 FROM #tb WHERE a = 1)
    begin
        -- 檔案已存在:使用 Excel ODBC 驅動程式開啟現有檔案
        SET @constr = 'DRIVER={Microsoft Excel Driver (*.xls)};DSN='''';READONLY=FALSE'
                    + ';CREATE_DB="' + @sql + '";DBQ=' + @sql;
    end
    else
    begin
        -- 檔案不存在:使用 Jet OLEDB 建立新的 Excel 5.0 格式檔案
        SET @constr = 'Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties="Excel 5.0;HDR=YES'
                    + ';DATABASE=' + @sql + '"';
    end

    DROP TABLE #tb;

    -- 建立 ADODB.Connection 物件
    EXEC @err = sp_OACreate 'ADODB.Connection', @obj OUT;
    IF @err <> 0 GOTO ErrorHandler;

    -- 開啟連接
    EXEC @err = sp_OAMethod @obj, 'Open', NULL, @constr;
    IF @err <> 0 GOTO ErrorHandler;

    -- 動態產生 CREATE TABLE 陳述式
    SELECT @sql = '', @fdlist = '';

    SELECT @fdlist = @fdlist + ',[' + a.name + ']',
           @sql = @sql + ',[' + a.name + '] ' +
           CASE
               WHEN b.name IN ('char','nchar','varchar','nvarchar') THEN
                   'TEXT(' + CAST(CASE WHEN a.length > 255 THEN 255 ELSE a.length END AS VARCHAR) + ')'
               WHEN b.name IN ('tinyint','int','bigint') THEN 'INT'
               WHEN b.name IN ('smalldatetime','datetime') THEN 'DATETIME'
               WHEN b.name IN ('money','smallmoney') THEN 'MONEY'
               ELSE b.name
           END
    FROM syscolumns a
    LEFT JOIN systypes b ON a.xtype = b.xusertype
    WHERE b.name NOT IN ('image','text','uniqueidentifier','sql_variant','ntext','varbinary','binary','timestamp')
      AND OBJECT_ID(@tbname) = a.id
    ORDER BY a.colid;

    -- 移除開頭逗號
    IF LEN(@sql) > 0 SET @sql = SUBSTRING(@sql, 2, LEN(@sql));
    IF LEN(@fdlist) > 0 SET @fdlist = SUBSTRING(@fdlist, 2, LEN(@fdlist));

    -- 建立工作表 (若不存在)
    SET @sql = 'CREATE TABLE [' + @tbname + '] (' + @sql + ')';
    EXEC @err = sp_OAMethod @obj, 'Execute', NULL, @sql;
    IF @err <> 0 GOTO ErrorHandler;

    -- 匯入資料
    SET @sql = 'INSERT INTO [' + @tbname + '] (' + @fdlist + ') SELECT ' + @fdlist + ' FROM [' + @tbname + ']';
    EXEC @err = sp_OAMethod @obj, 'Execute', NULL, @sql;
    IF @err <> 0 GOTO ErrorHandler;

    -- 清理資源
    EXEC sp_OADestroy @obj;
    RETURN 0;

ErrorHandler:
    EXEC sp_OAGetErrorInfo @obj, @src OUT, @desc OUT;
    RAISERROR('匯出失敗: %s - %s', 16, 1, @src, @desc);
    EXEC sp_OADestroy @obj;
    RETURN -1;
END
GO

呼叫範例

-- 匯出「地區資料」表到 C:\aa.xls
EXEC p_exporttb @tbname = N'地區資料', @path = N'C:\', @fname = N'aa.xls';

運作原理說明

  1. 檔案偵測: 使用 xp_fileexist 判斷目標檔案是否存在。
  2. 連接字串切換:
    • 檔案存在 → 使用 Microsoft Excel Driver (*.xls) ODBC 驅動程式開啟現有檔案 (ReadOnly=False)。
    • 檔案不存在 → 使用 Microsoft.Jet.OLEDB.4.0 Provider 建立 Excel 5.0 格式新檔案。
  3. 動態建表: 讀取 syscolumns 系統表取得欄位定義,轉換為 Excel/ Jet 支援的資料類型 (TEXT, INT, DATETIME, MONEY 等),排除不支援的類型 (image, text, ntext 等)。
  4. 資料寫入: 以 INSERT INTO ... SELECT 將資料從 SQL Server 表寫入 Excel 工作表。

限制與注意事項

  • 資料類型支援: 僅支援標準類型 (字串、數值、日期、貨幣);TEXT、NTEXT、IMAGE、VARBINARY、TIMESTAMP、SQL_VARIANT、UNIQUEIDENTIFIER 等將被忽略。
  • Excel 版本: 產生為 Excel 5.0 (BIFF8) 格式,相容 Excel 97-2003 (.xls)。若需 .xlsx 格式,需改用 ACE OLEDB 12.0/16.0 Provider 並調整連接字串。
  • 權限需求: SQL Server 服務帳號需具備目標資料夾的寫入權限;且需啟用 Ole Automation Procedures 伺服器選項 (sp_configure 'Ole Automation Procedures', 1; RECONFIGURE;)。
  • 64 位元環境: 64 位元 SQL Server 需安裝 64 位元的 Microsoft Access Database Engine (ACE) 才能使用 Jet/ACE Provider。
  • 大量資料: 透過 OLE Automation 逐筆寫入效率較低,百萬列以上資料建議改用 SSIS、BCP 或 CLR 存儲程序。

結語

p_exporttb 提供一個零第三方工具、純 T-SQL 即可將資料表匯出為真實 Excel 檔案的方案,適合輕量級報表自動化需求。部署前請在測試環境驗證權限與驅動程式相容性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved