2017-08-02 72 views
0

我有一个使用C#NI DAQmx代码生成的DataTable。我想把这个DataTable放在一个Excel文件中,当选中CheckBox时。 DAQmx代码一次记录此数据的“x”个样本数。当这个数字很高时,程序很慢,但它仍然有效。我想一次录制少量的样本,然后将这些数据保存到Excel文件中。如何使用DataTable连接Excel文件?

在我当前的代码,在Excel文件中的数据被不断改写。这是不可取的,因为我需要所有记录的数据。

目前当检查箱中的数据将积极记录,但它不会串连。我尝试了很多搜索,并为此探索了很多方法,但我还没有完全适应任何需求。

相关代码将包含在下面。任何帮助表示赞赏,谢谢。

注:数据并不一定是一个.xlsx文件。它可以是一个.csv

此代码是通过DAQmx的数据表生成:

private void DataToDataTable(AnalogWaveform<double>[] sourceArray, ref DataTable dataTable) 
    { 
     // Iterate over channels 
     int currentLineIndex = 0; 
     string test = currentLineIndex.ToString(); 

     foreach (AnalogWaveform<double> waveform in sourceArray) 
     { 
      for (int sample = 0; sample < waveform.Samples.Count; ++sample) 
      { 
       if (sample == 50) 
        break; 

       dataTable.Rows[sample][currentLineIndex] = waveform.Samples[sample].Value; 
      } 
      currentLineIndex++;  
     } 
    } 

    public void InitializeDataTable(AIChannelCollection channelCollection, ref DataTable data) 
    { 
     int numOfChannels = channelCollection.Count; 
     data.Rows.Clear(); 
     data.Columns.Clear(); 
     dataColumn = new DataColumn[numOfChannels]; 
     int numOfRows = 50; 

     for (int currentChannelIndex = 0; currentChannelIndex < numOfChannels; currentChannelIndex++) 
     { 
      dataColumn[currentChannelIndex] = new DataColumn() 
      { 
       DataType = typeof(double), 
       ColumnName = channelCollection[currentChannelIndex].PhysicalName 
      }; 
     } 

     data.Columns.AddRange(dataColumn); 

     for (int currentDataIndex = 0; currentDataIndex < numOfRows ; currentDataIndex++) 
     { 
      object[] rowArr = new object[numOfChannels]; 
      data.Rows.Add(rowArr); 
     } 
    } 

这是我目前保存到一个Excel文件的方法:既然你提到它

 private void Excel_cap_CheckedChanged(object sender, EventArgs e) 
    { 

        int i = 0; 
     for (excel_cap.Checked = true; excel_cap.Checked == true; i ++) { 

      { 
       StringBuilder sb = new StringBuilder(); 

       IEnumerable<string> columnNames = dataTable.Columns.Cast<DataColumn>(). 
                Select(column => column.ColumnName); 
       sb.AppendLine(string.Join(",", columnNames)); 

       foreach (DataRow row in dataTable.Rows) 
       { 
        IEnumerable<string> fields = row.ItemArray.Select(field => field.ToString()); 
        sb.AppendLine(string.Join(",", fields)); 
       } 

       File.AppendAllText(filename_box.Text, sb.ToString()); 

      } 
     } 
    } 

回答

0

不必是Excel,它可以是CSV,那么你可以使用你的CSV代码,但将File.WriteAllText行更改为File.AppendAllText,它将追加文本而不是替换现有文件。如果文件不存在,将会创建文件AppendAllText

File.AppendAllText("test.csv", sb.ToString()); 
+0

这非常有帮助。但是,你可以看看我编辑我当前的代码吗?我在你的改变中添加了它,它会在复选框更改后附加文件。只要'excel_cap.Checked = true',我就希望文件不断地附加新信息。我知道这是一个业余问题,但任何想法我可以解决这个问题? –

+0

@ScottMyers - 我看过代码,我想我会遵循你的新问题,但在SO上,如果你需要另一部分/第二个问题的帮助,你需要发布一个新问题。为了帮助你指出正确的方向,这听起来像你有生产者/消费者类型的问题。您应该考虑可能正在研究ConcurrentQueue,并且可能会保持文件的打开状态,并在队列中有数据时添加,但不知道更多关于此问题的信息,但很难给出答案。 – pstrjds

+0

啊,好的,谢谢。对不起菜鸟的错误。我感谢你的帮助! –

0

您确定您使用的是EPPlus吗?这CreateExcelFile看起来像是a copied code snippet

随着EPPlus,这将是那么容易,因为

using (var package = new ExcelPackage(new FileInfo(@"a.xslx"))) 
{ 
    if (!package.Workbook.Worksheets.Any()) 
     package.Workbook.Worksheets.Add("sheet"); 
    var sheet = package.Workbook.Worksheets.First(); 
    var appendRow = (sheet.Dimension?.Rows ?? 0) + 1; 
    sheet.Cells[appendRow, 1].LoadFromDataTable(new DataTable(), false); 
    package.SaveAs(new FileInfo(@"a.xslx")); 
} 

它看起来像你有一些对象,然后将其转换为DataTable,然后将它们写入到Excel/CSV。如果你跳过到DataTable的转换,你会加快速度。 EPPlus有LoadFromCollection,它可能只与AnalogWaveform<double>一起使用。

无耻的广告:我这些片段从我blog post about EPPlus

+0

我可能可以更好地标记这个。你是对的,那是代码片段的来源。我原本打算使用EPPlus,但无法适应它。我在'LoadFromDataTable'部分的代码中出现错误。它表示'方法没有超载'和'有1个参数'。任何想法为什么?另外,这将工作与两列数据? –

+0

错过第二个参数:'bool PrintHeaders' – Laoujin

+0

现在,该行('var appendRow = sheet.Dimension.Rows + 1;')正在抛出一个('NullReferenceException')错误。特别是('OfficeOpenXml.ExcelWorksheet.Dimension.get返回null')你知道如何解决这个问题吗? –