使用COM Interop复制Excel工作表失去单元格颜色

我已经尝试过使用COM Interop合并工作表的各种方法。

这是我最后的结果(为了简洁,省略了不必要的代码):

public bool CombineWorkBooks(string exportFilePath, IEnumerable<string> filesToMergeFrom, bool deleteRawFiles) { var success = false; Excel.Application xlApp = null; Excel.Workbook mergeToWorkbook = null; Excel.Workbooks mergeToWorkbooks = null; Excel.Sheets mergeToWorksheets = null; Excel.Worksheet defaultWorksheet = null; try { if (filesToMergeFrom == null) { return false; } xlApp = new Excel.Application { DisplayAlerts = false, Visible = false, CutCopyMode = Excel.XlCutCopyMode.xlCopy }; mergeToWorkbooks = xlApp.Workbooks; mergeToWorkbook = mergeToWorkbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet); mergeToWorksheets = mergeToWorkbook.Worksheets; // Get the reference for the [first] empty default worksheet if (mergeToWorksheets.Count > 0) { defaultWorksheet = mergeToWorksheets[1] as Excel.Worksheet; } if (defaultWorksheet == null) { return false; } var reportSheetIndex = 1; var fileMergeCount = 0; foreach (var mergeFromFilename in filesToMergeFrom) { fileMergeCount++; Excel.Workbook sourceWorkbook = null; Excel.Sheets childSheets = null; // Make sure file is still there... if (!File.Exists(mergeFromFilename)) { continue; } try { // Open source file sourceWorkbook = mergeToWorkbooks.Open(mergeFromFilename, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); childSheets = sourceWorkbook.Worksheets; if (childSheets != null) { var sheetsCopiedFromSource = 0; // childSheets.Copy(defaultWorksheet, Type.Missing); for (int iChildSheet = 1; iChildSheet <= childSheets.Count; iChildSheet++) { Excel.Worksheet sourceWorksheet = null; try { sourceWorksheet = childSheets[iChildSheet] as Excel.Worksheet; if (sourceWorksheet != null) { string name = string.Format(baseSheetName, reportSheetIndex.ToString("D4", new CultureInfo(CultureInfo.CurrentCulture.Name))); // Assigning the worksheet name sourceWorksheet.Name = Truncate(name, 31); // only 31 char max // Copy the worksheet before the default sheet sourceWorksheet.Copy(defaultWorksheet, Type.Missing); reportSheetIndex++; sheetsCopiedFromSource++; } } finally { disposeCOMObject(sourceWorksheet); } } // Close the childbook - for some reason, calling close below may cause an // exception -> System.Runtime.InteropServices.COMException (0x80010108): The object invoked has disconnected from its clients. try { sourceWorkbook.Close(false, Type.Missing, Type.Missing); } catch (COMException comException) { if (comException.ErrorCode != 0x80010108) { throw; } _messages.Add("Caught COMException, discarding it."); } _messages.Add(string.Format("Successfully copied {0} worksheets from report file: '{1}'", sheetsCopiedFromSource, mergeFromFilename)); } } catch (Exception ex) { _messages.Add(string.Format("An error occurred processing file '{0}'.", mergeFromFilename)); } finally { disposeCOMObject(childSheets); disposeCOMObject(sourceWorkbook); } } // Delete the empty default worksheet defaultWorksheet.Delete(); // Select the first sheet. if (mergeToWorksheets.Count > 0) { Excel.Worksheet firstSheet = null; try { firstSheet = mergeToWorksheets[1] as Excel.Worksheet; if (firstSheet != null) { firstSheet.Select(Type.Missing); firstSheet.Range["A1"].Select(); } } finally { disposeCOMObject(firstSheet); } } // Determine the file extension var fileExt = GetExcelExtension(); if (string.IsNullOrEmpty(Path.GetExtension(exportFilePath))) { exportFilePath = string.Format("{0}.{1}", exportFilePath, fileExt); } else if (Path.GetExtension(exportFilePath) != string.Format(".{0}", fileExt)) { exportFilePath = Path.ChangeExtension(exportFilePath, fileExt); } _mergeOutputFile = exportFilePath; // Save the merged output mergeToWorkbook.SaveAs(exportFilePath, Excel.XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); // Close file mergeToWorkbooks.Close(); xlApp.DisplayAlerts = true; success = true; return true; } catch (Exception ex) { return false; } finally { disposeCOMObject(defaultWorksheet); disposeCOMObject(mergeToWorksheets); disposeCOMObject(mergeToWorkbook); disposeCOMObject(mergeToWorkbooks); // Quit Excel. if (xlApp != null) { xlApp.Quit(); disposeCOMObject(xlApp); } // Only delete source files upon success... if (success && deleteRawFiles) { deleteTemporaryFiles(filesToMergeFrom); } // Clean up remaining resources GC.Collect(); GC.WaitForPendingFinalizers(); } } 

现在 – 这一切都很好。 但是…合并文件的单元格/行内部的颜色都搞砸了(通常是黑色和紫色 – 3岁可能更喜欢)。 源工作表有一些高亮的颜色或白色以外的背景(内部)颜色的行。

如果我添加下面的代码,我可以将合并文件中的所有单元格颜色重置为白色,但是我没有成功保存原始源表单的颜色。

  // Reset the background colour in the cells to white. For some reason the worksheet copy // operation screws up the cell backgrounds - pinks, purples and other business-like // colours. foreach (Excel.Worksheet targetWorksheet in mergeToWorkbook.Worksheets) { var usedRange = targetWorksheet.UsedRange; usedRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.White); } 

我遇到了同样的问题,并发现以下Microsoft支持说明: http : //support.microsoft.com/kb/2465477他们在这里提到一些解决方法。 对于我来说,下面的解决scheme工作:只需将新的工作簿的颜色scheme设置为旧的工作簿的颜色scheme,如下所示:

 mergeToWorkbook.Colors = sourceWorkbook.Colors;