我有以下代码从Excel工作表中读取数据并将其转换为管道分隔的文本文件。有用。问题是它很慢,因为我必须一次读取1个单元格才能添加管道。
我想知道是否有更好的方法可以做到这一点,即一步将数据读入内存/数组并在那里采取行动。
public string Process(string filename)
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range range;
string str = "";
int rCnt = 0;
int cCnt = 0;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(filename, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); //Use the 1st worksheet
StreamWriter sw = new StreamWriter(destpath);
range = xlWorkSheet.UsedRange;
for (rCnt = 1; rCnt <= range.Rows.Count; rCnt++)
{
if ((rCnt % 1000) == 0)
{
txtProgress.Text = "Rows processed: "+ rCnt;
}
for (cCnt = 1; cCnt <= range.Columns.Count; cCnt++)
{
str = str + ToStr((range.Cells[rCnt, cCnt] as Excel.Range).Value2) + "|";
}
sw.WriteLine(str);
str = "";
}
xlWorkBook.Close(true, null, null);
xlApp.Quit();
sw.Close();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
MessageBox.Show("Complete","Status");
return "Success";
}
public static string ToStr(object readField)
{
if ((readField != null))
{
if (readField.GetType() != typeof(System.DBNull))
{
return Convert.ToString(readField);
}
else
{
return "";
}
}
else
{
return "";
}
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
答案 0 :(得分:1)
如果您打算只对excel文件内容执行读取,我建议您使用ExcelDataReader库Link,它将worksheetData提取到DataSet对象中。
static void Main(string[] args)
{
IExcelDataReader reader = null;
string FilePath = "PathToExcelFile";
//Load file into a stream
FileStream stream = File.Open(FilePath, FileMode.Open, FileAccess.Read);
//Must check file extension to adjust the reader to the excel file type
if (System.IO.Path.GetExtension(FilePath).Equals(".xls"))
{
reader = ExcelReaderFactory.CreateBinaryReader(stream);
}
else if (System.IO.Path.GetExtension(FilePath).Equals(".xlsx"))
{
reader = ExcelReaderFactory.CreateBinaryReader(stream);
}
if (reader != null)
{
//Fill DataSet
System.Data.DataSet result = reader.AsDataSet();
try
{
//Loop through rows for the desired worksheet
//In this case I use the table index "0" to pick the first worksheet in the workbook
foreach (DataRow row in result.Tables[0].Rows)
{
string FirstColumn = row[0].ToString();
}
}
catch
{
}
}
}
答案 1 :(得分:0)
您可以使用LinqToExcel nuget包
https://www.nuget.org/packages/LinqToExcel/1.10.1
示例代码:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[CSDN_CreateDemandeAppro]
@EXER_FIN nvarchar(8),
@UNIT_ADM nvarchar(6),
@NOM_CONT nvarchar(30),
@MNT_TOTAL numeric(15, 2)
AS
DECLARE
@NO_DA nvarchar(8),
@TYPE nchar(1),
@STAT nchar(1),
@ETAT nchar(1),
@IND_ENG nchar(1),
@IND_APPR nchar(1),
@TYPE_TRAIT nchar(1),
@TEL nvarchar(11),
@POSTE nvarchar(5),
@NOM_ACHET nvarchar(30),
@COMMENT_ACHET nvarchar(255),
@DATE_CREAT smalldatetime,
@DATE_MAJ smalldatetime,
@DATE_APPR smalldatetime,
@CODE_FOND tinyint,
@NO_COMM_DOFIN nvarchar(9),
@NO_MAG nvarchar(6),
@NO_SEQ int,
@NO_DA_OUT int
BEGIN TRAN
SELECT @NO_DA = PROC_NO_DA FROM ACH_UNIT_ADM_NUM WHERE UNIT_ADM = @UNIT_ADM and EXER_FIN = @EXER_FIN ;
UPDATE ACH_UNIT_ADM_NUM SET PROC_NO_DA = @NO_DA + 1 WHERE UNIT_ADM = @UNIT_ADM and EXER_FIN = @EXER_FIN ;
COMMIT;
SET @TYPE = '0';
SET @STAT = '3';
SET @ETAT = 'C';
SET @IND_ENG = '0';
SET @IND_APPR = '0';
SET @TYPE_TRAIT = '1';
SET @TEL = NULL;
SET @POSTE = NULL;
SET @NOM_ACHET = NULL;
SET @COMMENT_ACHET = 'APPROVISIONNEMENT.CSDN.QC.CA';
SET @DATE_CREAT = GETDATE();
SET @DATE_MAJ = GETDATE();
SET @DATE_APPR = NULL;
SET @CODE_FOND = '1';
SET @NO_COMM_DOFIN = NULL;
SET @NO_MAG = NULL;
SET @NO_SEQ = 1;
SET @NO_DA_OUT = 0;
INSERT INTO DBO.ACH_DA
VALUES (
@EXER_FIN,
@NO_DA,
@UNIT_ADM,
@TYPE,
@STAT,
@ETAT,
@IND_ENG,
@IND_APPR,
@TYPE_TRAIT,
@NOM_CONT,
@TEL,
@POSTE,
@NOM_ACHET,
@COMMENT_ACHET,
@DATE_CREAT,
@DATE_MAJ,
@DATE_APPR,
@MNT_TOTAL,
@NO_SEQ,
@CODE_FOND,
@NO_COMM_DOFIN,
@NO_MAG);
Select @NO_DA;