繁体   English   中英

使用C#将数据追加到现有Excel文件

[英]Appending data to existing Excel file using C#

我是C#的新手,我想将一些数据从C#中的DataGridView导出到Excel文件中。 用户填写了datagridview的输入。

当前,我的程序可以创建一个excel文件以及datagridview中的值,并以给定的日期作为文件名。

我的问题是,如果excel文件已经存在,我似乎找不到从gridview追加数据的方法,它会覆盖当前的excel文件。

任何帮助/提示/建议都将受到高度赞赏。

谢谢 :)

这是我的代码:

Microsoft.Office.Interop.Excel.Application xlApp;          
Microsoft.Office.Interop.Excel.Workbook xlWorkBook; 
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
Microsoft.Office.Interop.Excel.Sheets xlBigSheet;
Microsoft.Office.Interop.Excel.Sheets xlSheet;
object misValue;
String newPath;

private void buttonOK_Click(object sender, EventArgs e)
{
    createXLSfile();
}

private void createXLSfile(){
    String cDate = datePicker.Value.ToShortDateString();
    String cMonth = datePicker.Value.ToString("MMMM");
    String cYear = datePicker.Value.ToString("yy");
    String cDay = datePicker.Value.ToString("dd");

    String fName = cDay + "-" + cMonth+ "-" + cYear + ".xls";

    String mainPath = @"C:\Users\User1\Desktop\" + cYear;
    String folderPath = System.IO.Path.Combine(mainPath, cMonth);
    String excelPath = System.IO.Path.Combine(folderPath, fName);

    System.IO.Directory.CreateDirectory(mainPath);
    System.IO.Directory.CreateDirectory(folderPath);

    String fNameOnly = Path.GetFileNameWithoutExtension(excelPath);
    String extension = Path.GetExtension(excelPath);
    String path = Path.GetDirectoryName(excelPath);
    newPath = excelPath;

    if(File.Exists(newPath))
    {
        existingFile();
    }else
    {
        newFile();
    }
    MessageBox.Show("Submitted");
}

private void newFile()
{
    xlApp = new Microsoft.Office.Interop.Excel.Application();
    xlApp.Visible = true;
    misValue = System.Reflection.Missing.Value;
    xlWorkBook = xlApp.Workbooks.Add(misValue);
    xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

    xlWorkSheet = xlWorkBook.Sheets["Sheet1"];
    xlWorkSheet = xlWorkBook.ActiveSheet;
    xlWorkSheet.Name = "Sheet1";

    xlWorkSheet.Cells[2, 1] = "Header1";
    xlWorkSheet.Cells[2, 2] = "Header2";
    xlWorkSheet.Cells[2, 3] = "Total";
    getData();

    xlWorkBook.SaveAs(newFullPath, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal, misValue,
    misValue, misValue, misValue, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
    xlWorkBook.Close(true, misValue, misValue);
    xlApp.Quit();
    Marshal.ReleaseComObject(xlWorkSheet);
    Marshal.ReleaseComObject(xlWorkBook);
    Marshal.ReleaseComObject(xlApp);
}

private void existingFile()
{
    xlApp = new Microsoft.Office.Interop.Excel.Application();
    xlApp.Visible = true;
    xlWorkBook = xlApp.Workbooks.Open(newPath, 0, 
                false, 5, "", "", false, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows,
                 "", true, false, 0, true, false, false);

    xlBigSheet = xlWorkBook.Worksheets;
    string x = "Sheet1";
    xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlBigSheet.get_Item(x);

    getData();

    xlWorkBook.SaveAs(newPath, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal,
            misValue, misValue, misValue, misValue, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive,
            misValue, misValue, misValue,
            misValue, misValue);

    xlWorkBook.Close(misValue, misValue, misValue);
    xlWorkBook = null;
    xlApp.Quit();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
}

private void getData()
{
    double a,b,c,d,total = 0;
    int lastRow_ = 3;

    foreach(DataGridViewRow r in dataGridView1.Rows)
    {
        if(!r.IsNewRow)
        {
            a = Convert.ToDouble(r.Cells[2].Value);
            b = Convert.ToDouble(r.Cells[3].Value);
            c = Convert.ToDouble(r.Cells[4].Value);
            d = Convert.ToDouble(r.Cells[5].Value);

            total = a + b + c + d;

            xlWorkSheet.Cells[lastRow_, 1] = "Hi";
            xlWorkSheet.Cells[lastRow_, 2] = "Hello";
            xlWorkSheet.Cells[lastRow_, 3] = Convert.ToString(total);
            lastRow_ = xlWorkSheet.Cells.Find(
                        "*",
                        xlWorkSheet.Cells[1, 1],
                        misValue,
                        Microsoft.Office.Interop.Excel.XlLookAt.xlPart,
                        Microsoft.Office.Interop.Excel.XlSearchOrder.xlByRows,
                        Microsoft.Office.Interop.Excel.XlSearchDirection.xlPrevious,
                        misValue,
                        misValue,
                        misValue).Row + 1;
        }
    }
    total = 0;
}

更新1:仍然卡住。 一直试图遵循此链接: https : //www.codeproject.com/articles/5123/opening-and-navigating-excel-with-c

输出值

输出的Excel文件目录

这就是输出的excel文件中的内容

当需要将数据追加到现有工作表时,需要找出最后使用的行在哪里,并开始在该行之后添加数据。 您当前获得该“最后”行的代码很尴尬,因为一旦开始添加行,您将继续检查该“最后”行,这是不必要的。 getData()方法只是将数据添加到新Excel文件中,而最后一行无关紧要。 如果文件存在,则只需要获取最后使用的行并开始在下一行上导入数据。 我猜测随着代码的发展,发送GetData(RowToStart)方法的起始行索引并简单地增加lastRow_变量可能会更好,如下所示:无需继续检查最后一行。

private void getData(int lastRow_) {
  double a, b, c, d, total = 0;
  //int lastRow_ = 4;

  foreach (DataGridViewRow r in dataGridView1.Rows) {
    //if (!row.IsNewRow) {
    if (!r.IsNewRow) {
        a = Convert.ToDouble(r.Cells[2].Value);
      b = Convert.ToDouble(r.Cells[3].Value);
      c = Convert.ToDouble(r.Cells[4].Value);
      d = Convert.ToDouble(r.Cells[5].Value);

      total = a + b + c + d;

      xlWorkSheet.Cells[lastRow_, 1] = "Hi";
      xlWorkSheet.Cells[lastRow_, 2] = "Hello";
      xlWorkSheet.Cells[lastRow_, 3] = Convert.ToString(total);
      lastRow_++;
      //lastRow_ = xlWorkSheet.Cells.Find(
      //            "*",
      //            xlWorkSheet.Cells[1, 1],
      //            misValue,
      //            Microsoft.Office.Interop.Excel.XlLookAt.xlPart,
      //            Microsoft.Office.Interop.Excel.XlSearchOrder.xlByRows,
      //            Microsoft.Office.Interop.Excel.XlSearchDirection.xlPrevious,
      //            misValue,
      //            misValue,
      //            misValue).Row + 1;
    }
  }
  total = 0;
}

如果文件是新文件,则可以按如下所示调用此方法。

 .
 .
 .
  xlWorkSheet.Cells[3, 1] = "Header1";
  xlWorkSheet.Cells[3, 2] = "Header2";
  xlWorkSheet.Cells[3, 3] = "Total";
  getData(4);
 .
 .
 .

如果文件已经存在,并且需要将数据追加到现有工作表中,则需要获取最后使用的行,然后从下一行开始。 您可以像下面这样调用getData(RowToStart)

 .
 .
 .

 xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlBigSheet.get_Item("Sheet1");
 Microsoft.Office.Interop.Excel.Range last = xlWorkSheet.Cells.SpecialCells(Microsoft.Office.Interop.Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
 int lastUsedRow = last.Row;
 getData(lastUsedRow + 1);
 .
 .
 .

我希望这是有道理的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM