导出SQL查询结果至CSV/Excel时如何保留原始格式?
解决PowerShell导出SQL结果到Excel的多余列与格式问题
我来帮你搞定这两个头疼的问题——导出时出现多余列,还有长数字变成科学计数法导致SQL插入错误的情况:
一、先搞定多余列的问题
你直接导出$DataSet.Tables[0]时,其实是把DataRow对象的所有属性都导出去了,那些RowState、ItemArray都是DataRow自带的元数据,不是你要的业务列。要只导出表中的真实数据列,有两种简单方法:
方法1:指定要导出的列名
先把DataTable的列名取出来,再用Select-Object筛选这些列导出:
# 获取表的所有列名 $columnNames = $DataSet.Tables[0].Columns | Select-Object -ExpandProperty ColumnName # 只选择业务列导出,避开元数据属性 $DataSet.Tables[0] | Select-Object $columnNames | Export-Excel -Path "C:\temp\xxxx.xlsx" -AutoSize
方法2:把DataRow转成自定义对象
如果需要更灵活的处理,可以把每一行DataRow转换成PSCustomObject,只保留业务列:
$DataSet.Tables[0].Rows | ForEach-Object { $row = $_ $customObj = [PSCustomObject]@{} foreach ($col in $DataSet.Tables[0].Columns) { $customObj | Add-Member -NotePropertyName $col.ColumnName -NotePropertyValue $row[$col.ColumnName] } $customObj } | Export-Excel -Path "C:\temp\xxxx.xlsx" -AutoSize
这样导出的Excel就只有你需要的业务列了。
二、保留长数字的原始格式(避免科学计数法)
长数字变成8.01540262867236E+16是因为Excel默认把它识别成数值类型,自动用科学计数法显示,而且还会丢失精度。要解决这个问题,核心是让Excel把这些列当成文本处理,这里有两种靠谱的方式:
方式1:用Export-Excel直接指定列格式
ImportExcel模块支持通过-Column参数给特定列设置格式,直接把长数字列设为文本类型:
# 先获取列名 $columnNames = $DataSet.Tables[0].Columns.ColumnName # 配置列格式:把codeexterne设为文本,其他列按需配置 $columnConfigs = @( @{ Name = 'codeexterne'; DataType = 'Text' } ) # 一步导出,同时解决多余列和格式问题 $DataSet.Tables[0] | Select-Object $columnNames | Export-Excel -Path "C:\temp\xxxx.xlsx" -AutoSize -Column $columnConfigs
这样导出后,codeexterne列会被强制设为文本格式,长数字会完整显示,不会变成科学计数法。
方式2:如果必须先转CSV再导Excel
如果你还是需要先导出CSV,那要确保CSV里的长数字被识别为文本。可以在导出CSV时给长数字加个单引号前缀(Excel会把带单引号的内容当成文本):
# 导出CSV时,给codeexterne列加单引号前缀 $DataSet.Tables[0] | Select-Object iddoss, @{Name='codeexterne'; Expression={"'" + $_.codeexterne}} | Export-Csv -Path "C:\temp\xxxx.csv" -Delimiter ';' -NoTypeInformation -Encoding UTF8 # 导入CSV后再导出Excel,此时codeexterne是文本格式 $csvData = Import-Csv -Path "C:\temp\xxxx.csv" -Delimiter ';' # 如果不想保留单引号,导出时可以去掉 $csvData | Select-Object iddoss, @{Name='codeexterne'; Expression={$_.codeexterne -replace "^'"}} | Export-Excel -Path "C:\temp\xxxx.xlsx" -AutoSize
三、推荐的完整解决方案
直接处理DataTable并指定列格式,一步到位,既高效又不会出问题:
# 获取所有业务列名 $columnNames = $DataSet.Tables[0].Columns.ColumnName # 配置需要特殊处理的列(这里是codeexterne设为文本) $columnSettings = @( @{ Name = 'codeexterne'; DataType = 'Text' } ) # 导出Excel $DataSet.Tables[0] | Select-Object $columnNames | Export-Excel -Path "C:\temp\xxxx.xlsx" -AutoSize -Column $columnSettings
这样导出的Excel既没有多余列,长数字也会以原始格式保留,生成SQL插入语句时就能得到正确的80154026286723600了。
内容的提问来源于stack exchange,提问作者Mou Amg
相关产品推荐
相关产品推荐

