在Excel中使用Excel Interop提交对excel文件的更改

我仍然坚持在这个代码和错误不断显示..我有excel文件,是近24列,我想适应它到一个7列excel文件,因为我只有7个工作的软件,我不'不想从头开始编写软件,所以你会看到一些删除和列的isertion。

我有这个Excel文件中有5个列,有“x”值或null。

我想要做的是在范围A1和B1之间创build一个名为category的新列,所以如果列5中有一个x,我在类别字段中写入E,否则如果x在第6列然后我在类别列中写P ..等等。 然后我需要删除这些不再需要的5列(范围E1:I1)

问题是,当我debugging代码,我可以看到值,[]具有列插入,并已正确传输的值,但是当temp_data.csv产生,它有删除后新的Excel文件,所以现在它包含11列,但新的类别列连同值不存在…

Microsoft.Office.Interop.Excel.Workbook workbook = xl.Workbooks.Open(p_sUBKPath, Type.Missing, false, 4, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); Microsoft.Office.Interop.Excel.Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets[1]; Microsoft.Office.Interop.Excel.Range range = ws.UsedRange; // delete columns that we don't need from the new excel file Microsoft.Office.Interop.Excel.Range range2 = ws.get_Range("A1","A1"); range2.EntireColumn.Delete(); Microsoft.Office.Interop.Excel.Range range3 = ws.get_Range("B1", "B1"); range3.EntireColumn.Delete(); Microsoft.Office.Interop.Excel.Range range4 = ws.get_Range("D1", "L1"); range4.EntireColumn.Delete(); Microsoft.Office.Interop.Excel.Range range5 = ws.get_Range("I1", "M1"); range5.EntireColumn.Delete(); Microsoft.Office.Interop.Excel.Range range6 = ws.get_Range("K1", "K1"); range6.EntireColumn.Delete(); //insert a new column ( Category) Microsoft.Office.Interop.Excel.Range range7 = ws.get_Range("B1", "B1"); range7.EntireColumn.Insert(XlInsertShiftDirection.xlShiftToRight); object[,] tempVal = (object[,])range.Value2; tempVal[1, 2] = (object)"Category"; for (int row = 2; row <= tempVal.GetUpperBound(0); row++) { try { if ((!String.IsNullOrEmpty((string)tempVal[row, 5])) && (string)tempVal[row, 5] == "x") { tempVal[row, 2] = (string)"E"; } else if ((!String.IsNullOrEmpty((string)tempVal[row, 6])) && (string)tempVal[row, 6] == "x") { tempVal[row, 2] = (string)"P"; } else if ((!String.IsNullOrEmpty((string)tempVal[row, 7])) && (string)tempVal[row, 7] == "x") { tempVal[row, 2] = (string)"Phy"; } else if ((!String.IsNullOrEmpty((string)tempVal[row, 8])) && (string)tempVal[row, 8] == "x") { tempVal[row, 2] = (string)"L"; } else if ((!String.IsNullOrEmpty(tempVal[row, 9].ToString())) && (string)tempVal[row, 9] == "x") { tempVal[row, 2] = (string)"Ex"; } else MessageBox.Show("unknow"); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } object[,] values = tempVal; if (Convert.ToString(values[1, 1]).ToUpper().Trim() == "SHORT NAME" && Convert.ToString(values[1, 2]).ToUpper().Trim() == "CATEGORY" && Convert.ToString(values[1, 3]).ToUpper().Trim() == "LONG NAME EN" && Convert.ToString(values[1, 4]).ToUpper().Trim() == "LONG NAME DE" && Convert.ToString(values[1, 5]).ToUpper().Trim() == "ELEMENT" && Convert.ToString(values[1, 6]).ToUpper().Trim() == "PROPERNAME" && Convert.ToString(values[1, 7]).ToUpper().Trim() == "PHYSICAL" && Convert.ToString(values[1, 8]).ToUpper().Trim() == "LOGICAL" && Convert.ToString(values[1, 9]).ToUpper().Trim() == "EXTENSION" && Convert.ToString(values[1, 10]).ToUpper().Trim() == "CREATED BY" && Convert.ToString(values[1, 11]).ToUpper().Trim() == "CREATED ON" && Convert.ToString(values[1, 12]).ToUpper().Trim() == "STATE") { for (int row = 1; row <= values.GetUpperBound(0); row++) for (int col = 1; col <= values.GetUpperBound(1); col++) { string value = Convert.ToString(values[row, col]); if (value.Contains(",")) { range.Cells.set_Item(row, col, value.Replace(",", p_sPsuedostring)); } if (value.Contains(" ")) { range.Cells.set_Item(row, col, value.Replace(" ", p_sPsuedostring + " " + p_sPsuedostring)); } } if (File.Exists(System.Windows.Forms.Application.StartupPath + @"\Data_Temp.csv")) File.Delete(System.Windows.Forms.Application.StartupPath + @"\Data_Temp.csv"); //Save the Latest databse as Data_Temp.csv ws.SaveAs(System.Windows.Forms.Application.StartupPath + @"\Data_Temp.csv", Microsoft.Office.Interop.Excel.XlFileFormat.xlUnicodeText, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); xl.DisplayAlerts = true; try { xl.Workbooks[1].Close(false, Type.Missing, Type.Missing); } catch(Exception ex) { MessageBox.Show(ex.ToString()); } xl.Application.Quit(); xl.Quit(); l_bClosedSuccessfully = true; 

基于你的上面的评论,让我们说你的Excel文件看起来像这样。 我已经着色了需要删除的栏目黄色。

截图

在这里输入图像说明

逻辑

  1. 以相反的顺序删除列,以便列的顺序不会改变,否则您将不得不考虑新移动的列
  2. 避免使用usedrangeUsedRange还可以包含不必要的行/列,使代码变慢。 我find最后一个有数据的单元格,然后使用它的.Row.Column属性来构build我的范围,其中包含“X”
  3. 使用。 .Find和。 Findnext在您的范围内search“X”。 一旦你find了,find单元格的列号并从中减去2。 由于只有5列,因此只需使用IF条件检查列的值,然后从中减去2,然后确定要使用的keyword

代码

试试这个代码(TRIED AND TESTED)

 using System; using System.Windows.Forms; using System.IO; using Excel = Microsoft.Office.Interop.Excel; using System.Reflection; Namespace WindowsFormsApplication1 { public partial class Form1 : Form { Public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Excel.Application xlexcel; Excel.Workbook xlWorkBook; Excel.Worksheet xlWorkSheet; Excel.Range Rng, aCell, bCell; String sMsg = ""; object misValue = Missing.Value; xlexcel = new Excel.Application(); xlexcel.Visible = true; //~~> Open a File (Chnage filename as applicable) xlWorkBook = xlexcel.Workbooks.Open("C:\\MyFile.xlsx", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0); //~~> Set Sheet 1 as the sheet you want to work with xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); //~~> Delete relevant columns in reverse order //A,c,f,g,h,i,j,k,l,m,n,t,u,v,w,x,AA xlWorkSheet.get_Range("AA1", "AA1").EntireColumn.Delete(); xlWorkSheet.get_Range("T1", "X1").EntireColumn.Delete(); xlWorkSheet.get_Range("F1", "N1").EntireColumn.Delete(); xlWorkSheet.get_Range("C1", "C1").EntireColumn.Delete(); xlWorkSheet.get_Range("A1", "A1").EntireColumn.Delete(); //~~> Insert the Category Column xlWorkSheet.get_Range("B1", "B1").EntireColumn.Insert( Excel.XlInsertShiftDirection.xlShiftToRight); //~~> get the last row and the last column of your data range //~~> This is much better than using usedrange which might //'~~> include unnecessary ranges int lRow = xlWorkSheet.Cells.SpecialCells( Excel.XlCellType.xlCellTypeLastCell, Type.Missing).Row; int lCol = xlWorkSheet.Cells.SpecialCells( Excel.XlCellType.xlCellTypeLastCell, Type.Missing).Column; String Addr = xlWorkSheet.Cells[1, lCol].Address; //~~> This is to get the column name from column number String ColName = Addr.Split('$')[1]; //~~> This is your data range. I am assuming that Row 1 has headers Rng = xlWorkSheet.get_Range("C2:" + ColName + lRow, misValue); //~~> Find the first occurance of "X" aCell = Rng.Find("X",misValue,Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlWhole,misValue, Excel.XlSearchDirection.xlNext,misValue,misValue,misValue); //~~> Find the next occurance of "X" using FindNext if(aCell != null) { //~~> Get the column number and subtract 2 from it int col = aCell.Column-2; //~~> Choose the relevant keyword if (col == 1) { sMsg = "Element"; } else if (col == 2) { sMsg = "propername"; } else if (col == 3) { sMsg = "physical"; } else if (col == 4) { sMsg = "logical"; } else if (col == 5) { sMsg = "extension"; } //~~> Populate the Category Column xlWorkSheet.Cells[aCell.Row, 2].Value = sMsg; string sFirstFoundAddress = aCell.get_Address(true, true, Excel.XlReferenceStyle.xlA1, misValue, misValue); bCell = Rng.Cells.FindNext(aCell); string sAddress = bCell.get_Address(true, true, Excel.XlReferenceStyle.xlA1, misValue, misValue); //~~> FindNext until the first found cell is found again While (!sAddress.Equals(sFirstFoundAddress)) { //~~> Get the column number and subtract 2 from it col = bCell.Column-2; //~~> Choose the relevant keyword if (col == 1) { sMsg = "Element"; } else if (col == 2) { sMsg = "propername"; } else if (col == 3) { sMsg = "physical"; } else if (col == 4) { sMsg = "logical"; } else if (col == 5) { sMsg = "extension"; } xlWorkSheet.Cells[bCell.Row, 2].Value = sMsg; bCell = Rng.Cells.FindNext(bCell); sAddress = bCell.get_Address(true, true, Excel.XlReferenceStyle.xlA1, misValue, misValue); } } //~~> Once done close and quit Excel xlWorkBook.Close(true, misValue, misValue); xlexcel.Quit(); //~~> CleanUp releaseObject(xlWorkSheet); releaseObject(xlWorkBook); releaseObject(xlexcel); } 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(); } } } } 

ScreenShot (代码运行后):

在这里输入图像说明