如何将Excel Interop与ClosedXml混合使用:样式

时间:2018-01-29 11:40:27

标签: c# vsto excel-interop closedxml

我正在尝试在Excel VSTO加载项中实现以下功能:

从原始版本的Excel文件复制/应用单元格格式。

原因:在处理Excel文件时,我们偶尔需要更改文件的样式/颜色,以便只能处理某些单元格。处理完文件后,我们需要恢复原始的单元格格式。为此,我写了一个VSTO加载项。

它读取orignal文件,遍历所有使用过的单元格,并将每个单元格的格式应用于最终文件中的相应单元格(地址)。 它工作正常,但它通过Interop打开原始文件 - 这可能是一个问题,因为文件名不会改变。另外:表现不理想。另外:用户在操作过程中会看到原始文件,这会导致混淆。

因此我想"打开"通过ClosedXml的原始文件。 这就是我陷入困境的地方:

var xl = Globals.ThisAddIn.Application;
var dest = xl.ActiveWorkbook; //Interop
try
{
    var org = new XLWorkbook(pfad); //ClosedXml
    foreach (IXLWorksheet sheet in org.Worksheets)
    {
        var used = sheet.RangeUsed(true);
        Excel.Worksheet dsheet = dest.Sheets[sheet.Name];
        foreach (IXLCell cel in used.Cells(false))
        {
            var adr = cel.Address;
            var interior = dsheet.Range[adr].Interior;
            interior.Color = cel.Style.Fill.BackgroundColor;
            interior.Pattern = cel.Style.Fill.PatternColor;

            //Crash!
            //HRESULT: 0x800A03EC
            //...
            //...

            var borders = dsheet.Range[adr].Borders;
            var orgbord = cel.Style.Border;

            borders[Excel.XlBordersIndex.xlEdgeTop].LineStyle = orgbord.TopBorder;
            //Crash!
            //HRESULT: 0x800A03EC
            //...
            //...
        }
    }
    org.Dispose();
}
catch (Exception ex)
{
        log.WriteLine(ex.Message);
}

我认为问题是在Excel互操作中,Color / TintAndShade等内容以及borderstyle / Weight等边界比ClosedXml更精细地定义,这使得这两种不兼容?

此前有没有人尝试过类似的东西,知道怎么做?

如果我能以某种方式解决这个问题会很好,所以我并没有坚持所有的互操作。

1 个答案:

答案 0 :(得分:1)

没关系。我通过简单地关闭活动工作簿,使用ClosedXml完成所有繁琐的工作,然后重新打开来解决这个问题:

var xl = Globals.ThisAddIn.Application;
var dest = xl.ActiveWorkbook;
var dpfad = dest.FullName;
dest.Close();
var xdest = new XLWorkbook(dpfad);
var org = new XLWorkbook(pfad);
foreach (IXLWorksheet sheet in org.Worksheets)
{
    var used = sheet.RangeUsed(true);
    IXLWorksheet dsheet;
    xdest.TryGetWorksheet(sheet.Name, out dsheet);

    foreach (IXLCell cel in used.Cells(false))
    {
        var dcel = dsheet.Range(cel.WorksheetRow().RowNumber(),
            cel.WorksheetColumn().ColumnNumber(), cel.WorksheetRow().RowNumber(),
            cel.WorksheetColumn().ColumnNumber());
        dcel.Style = cel.Style;
    }
}
xdest.Save();
xdest.Dispose();
org.Dispose();
xl.Workbooks.Open(dpfad);