求助:SSIS脚本任务为何仅部分将Excel转换为CSV?
问题描述
本地Visual Studio环境运行Excel转CSV脚本正常,但部署到服务器后,无报错却仅导出12150行数据(原Excel约72400行),事件查看器无错误记录。脚本代码如下:
var directory = new DirectoryInfo(SourceFolderPath); FileInfo[] files = directory.GetFiles("*.xlsx"); //Declare and initialize variables string fileFullPath = ""; //Get one Book(Excel file at a time) foreach (FileInfo file in files) { // Chemin d'accès au fichier Excel string excelFilePath = file.FullName; // Chemin d'accès au fichier CSV string filename = file.Name.Replace(".xlsx", ""); string csvFilePath = DestinationFolderPath + filename + ".csv"; // Chaîne de connexion OLE DB pour Excel string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelFilePath + ";Extended Properties=\"Excel 12.0 XML;HDR=YES;IMEX = 1\""; // Requête SQL pour extraire les données de la feuille de calcul string sqlQuery = "SELECT * FROM [Journal$]"; // Créez une connexion OLE DB à Excel using (OleDbConnection connection = new OleDbConnection(connectionString)) { connection.Open(); // Exécutez la requête SQL pour extraire les données using (OleDbDataAdapter adapter = new OleDbDataAdapter(sqlQuery, connection)) { using (DataTable dataTable = new DataTable()) { adapter.Fill(dataTable); // Créez un writer pour écrire dans le fichier CSV using (StreamWriter writer = new StreamWriter(csvFilePath, false, System.Text.Encoding.UTF8)) { // Écrivez les en-têtes de colonne dans le fichier CSV foreach (DataColumn column in dataTable.Columns) { writer.Write(column.ColumnName); writer.Write(FileDelimited); } writer.WriteLine(); // Écrivez les données dans le fichier CSV foreach (DataRow row in dataTable.Rows) { foreach (var item in row.ItemArray) { string valeur = item.ToString().Replace("\n", " - ").Replace("\"", "").Replace("'", "").Replace(";", "-").Replace("|", "-"); writer.Write(valeur); writer.Write(FileDelimited); } writer.WriteLine(); } } } } } }
排查方向
- ACE驱动位数不匹配:服务器上的ACE驱动可能是32位,而应用编译为64位(反之亦然),导致读取数据时截断。检查服务器ACE驱动位数,确保和应用编译平台一致。
- 数据类型推断限制:ACE驱动默认根据前几行推断列类型,后续行若出现不同类型数据会被忽略或转为NULL。修改连接字符串的Extended Properties为
"Excel 12.0 XML;HDR=YES;IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text",强制所有列按文本读取。 - Excel文件异常:服务器上的Excel文件可能存在隐藏行、筛选状态,或传输时损坏。检查服务器端原文件,确认行数完整且无筛选、隐藏设置。
- 内存/资源限制:服务器内存不足导致
adapter.Fill(dataTable)无法加载全部数据,可尝试分批读取数据而非一次性加载到DataTable。 - 权限不足:应用程序池运行账户无Excel文件目录的完全控制权限,导致无法完整读取文件,检查并调整权限。
免费替代方案(支持处理换行等特殊字符)
推荐使用EPPlus(MIT协议,免费商用),无需依赖ACE驱动,能规避驱动带来的各类限制,原生支持处理特殊字符:
using OfficeOpenXml; using System.IO; // EPPlus 5+需设置许可证上下文 ExcelPackage.LicenseContext = LicenseContext.NonCommercial; // 商用请改为LicenseContext.Commercial var directory = new DirectoryInfo(SourceFolderPath); FileInfo[] files = directory.GetFiles("*.xlsx"); foreach (FileInfo file in files) { string csvFilePath = Path.Combine(DestinationFolderPath, $"{Path.GetFileNameWithoutExtension(file.Name)}.csv"); using (var package = new ExcelPackage(file)) { var worksheet = package.Workbook.Worksheets["Journal"]; int rowCount = worksheet.Dimension.Rows; int colCount = worksheet.Dimension.Columns; using (var writer = new StreamWriter(csvFilePath, false, System.Text.Encoding.UTF8)) { // 写入表头 for (int col = 1; col <= colCount; col++) { string header = worksheet.Cells[1, col].Text.Replace("\n", " - ").Replace("\"", "").Replace("'", "").Replace(";", "-").Replace("|", "-"); writer.Write(header); writer.Write(FileDelimited); } writer.WriteLine(); // 写入数据行 for (int row = 2; row <= rowCount; row++) { for (int col = 1; col <= colCount; col++) { string value = worksheet.Cells[row, col].Text.Replace("\n", " - ").Replace("\"", "").Replace("'", "").Replace(";", "-").Replace("|", "-"); writer.Write(value); writer.Write(FileDelimited); } writer.WriteLine(); } } } }
- 优势:无需安装ACE驱动,避免位数、类型推断问题;直接读取单元格内容,不会丢失数据;原生支持处理换行、特殊字符。
内容的提问来源于stack exchange,提问作者Steph
相关产品推荐
相关产品推荐

