/*
--ç¨BCPè¯è¯,ä¸è¡åç¨ä¸é¢çåå¨è¿ç¨
EXEC master..xp_cmdshell 'bcp "select * from test.dbo.Apo_village"
queryout "c:/Apo_SFZ.xlsx" -c -S"æå¡å¨" -U"sa" -P"å¯ç "'
*/
--è¿æ¯ç¨C#åçåå¨è¿ç¨,ä¸ç¥éä½ ä¼ä¸ä¼ç¼è¯å°SQL Server
--å¨æ°æ®åºè¿æ ·è°ç¨å°±æ¯äº
--Exec BulkCopyToXls 'SQLæ¥è¯¢è¯å¥','è·¯å¾','æ件å',æ大记å½æ°
--Exec BulkCopyToXls 'select * from 表','G:\Test','Table',60000
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
public partial class myProcedure
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void BulkCopyToXls(SqlString sql, SqlString savePath, SqlString tableName, SqlInt32 maxRecordCount)
{
if (sql.IsNull || savePath.IsNull || tableName.IsNull)
{
SqlContext.Pipe.Send(" è¾å
¥ä¿¡æ¯ä¸å®æ´ï¼");
}
//æ¯ä¸ªexcelæ件æ大容纳65534
ushort _maxRecordCount = ushort.MaxValue - 1;
if (maxRecordCount.IsNull == false && maxRecordCount.Value < ushort.MaxValue && maxRecordCount.Value > 0)
_maxRecordCount = (ushort)maxRecordCount.Value;
ExportXls(sql.Value, savePath.Value, tableName.Value, _maxRecordCount);
}
private static void ExportXls(string sql, string savePath, string tableName, System.UInt16 maxRecordCount)
{
//å建æ件路å¾
if (System.IO.Directory.Exists(savePath) == false)
{
System.IO.Directory.CreateDirectory(savePath);
}
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
conn.Open();
using (SqlCommand command = conn.CreateCommand())
{
command.CommandText = sql;
using (SqlDataReader reader = command.ExecuteReader())
{
int i = 0;
int totalCount = 0;
int tick = System.Environment.TickCount;
SqlContext.Pipe.Send(" å¼å§å¯¼åºæ°æ®");
while (true)
{
string fileName = string.Format(@"{0}/{1}.{2}.xls", savePath, tableName, i++);
int iExp = Write(reader, maxRecordCount, fileName);
long size = new System.IO.FileInfo(fileName).Length;
totalCount += iExp;
SqlContext.Pipe.Send(string.Format(" æ件{0}, å
±{1} æ¡, 大å°{2} åè", fileName, iExp, size.ToString("###,###")));
if (iExp < maxRecordCount) break;
}
tick = System.Environment.TickCount - tick;
SqlContext.Pipe.Send(" 导åºæ°æ®å®æ");
SqlContext.Pipe.Send("-------");
SqlContext.Pipe.Send(string.Format(" å
±{0} æ¡æ°æ®ï¼èæ¶{1}ms", totalCount, tick));
}
}
}
} private static void WriteObject(ExcelWriter writer, object obj, System.UInt16 x, System.UInt16 y)
{
//å¤æåæ°åè¿æ¯åå符
string type = obj.GetType().Name.ToString();
switch (type)
{
case "SqlBoolean":
case "SqlByte":
case "SqlDecimal":
case "SqlDouble":
case "SqlInt16":
case "SqlInt32":
case "SqlInt64":
case "SqlMoney":
case "SqlSingle":
if (obj.ToString().ToLower() == "null")
writer.WriteString(x, y, obj.ToString());
else
writer.WriteNumber(x, y, Convert.ToDouble(obj.ToString()));
break;
default:
writer.WriteString(x, y, obj.ToString());
break;
}
}
private static int Write(SqlDataReader reader, System.UInt16 count, string fileName)
{
int iExp = count;
ExcelWriter writer = new ExcelWriter(fileName);
writer.BeginWrite();
//åå段信æ¯
for (System.UInt16 j = 0; j < reader.FieldCount; j++)
{
writer.WriteString(0, j, reader.GetName(j));
}
//循ç¯ä¸è¡ä¸è¡è¯»å
¥æ°æ®
for (System.UInt16 i = 1; i <= count; i++)
{
if (reader.Read() == false)
{
iExp = i - 1;
break;
}
//循ç¯ä¸æ ¼ä¸æ ¼åå
¥æ°æ®
for (System.UInt16 j = 0; j < reader.FieldCount; j++)
{
WriteObject(writer, reader.GetSqlValue(j), i, j);
}
}
writer.EndWrite();
return iExp;
}
public class ExcelWriter
{
System.IO.FileStream _wirter;
//å建æ件
public ExcelWriter(string strPath)
{
_wirter = new System.IO.FileStream(strPath, System.IO.FileMode.OpenOrCreate);
}
//åæ°ç»
private void _writeFile(System.UInt16[] values)
{
foreach (System.UInt16 v in values)
{
byte[] b = System.BitConverter.GetBytes(v);
_wirter.Write(b, 0, b.Length);
}
}
//åæ件头
public void BeginWrite()
{
_writeFile(new System.UInt16[] { 0x809, 8, 0, 0x10, 0, 0 });
}
//æ件尾
public void EndWrite()
{
_writeFile(new System.UInt16[] { 0xa, 0 });
_wirter.Close();
}
//åæ°åå°åå
æ ¼
public void WriteNumber(System.UInt16 x, System.UInt16 y, double value)
{
_writeFile(new System.UInt16[] { 0x203, 14, x, y, 0 });
byte[] b = System.BitConverter.GetBytes(value);
_wirter.Write(b, 0, b.Length);
}
//åå符å°åå
æ ¼
public void WriteString(System.UInt16 x, System.UInt16 y, string value)
{
byte[] b = System.Text.Encoding.Default.GetBytes(value);
_writeFile(new System.UInt16[] { 0x204, (System.UInt16)(b.Length + 8), x, y, 0, (System.UInt16)b.Length });
_wirter.Write(b, 0, b.Length);
}
}
};