Why appending AutoFilter corrupts my excel file in this example?

前端 未结 2 1197
星月不相逢
星月不相逢 2020-12-02 00:51

Hi I use the below method to apply an AutoFilter :

public static void ApplyAutofilter(string fileName, string sheetName, string reference)
        {
                 


        
2条回答
  •  情深已故
    2020-12-02 01:00

    This happens because of where you are writing the autoFilter element in the XML. I opened a file that I had run your code on and opened it in the Open XML Productivity Tool. This showed that the error was

    Error message: Unexpected Child Element

    Looking at the ECMA-376 standard from here the XML for a Worksheet looks like this:

    
      
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
      
    
    

    Notice that it's a sequence so the order of the items matters. In my sample file above the autoFilter element was added after the pageMargins element which is contrary to the above schema.

    Changing the code to write the autoFilter element to the correct place fixes your code. I'm not sure if this is the most effecient way but this should work. It is essentially working backwards up the child elements of the workbook until it finds the first element that the autoFilter can be after. Once it finds that it uses the InsertAfter method to insert the autoFilter into the correct place:

    public static void ApplyAutofilter(string fileName, string sheetName, string reference)
    {
        using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true))
        {
            IEnumerable sheets = document.WorkbookPart.Workbook.GetFirstChild().Elements().Where(s => s.Name == sheetName);
            var arrSheets = sheets as Sheet[] ?? sheets.ToArray();
    
            string relationshipId = arrSheets.First().Id.Value;
            var worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(relationshipId);
    
            var autoFilter = new AutoFilter() { Reference = reference };
            OpenXmlElement preceedingElement = GetPreceedingElement(worksheetPart);
            worksheetPart.Worksheet.InsertAfter(autoFilter, preceedingElement);
    
            worksheetPart.Worksheet.Save();
        }
    }
    
    public static OpenXmlElement GetPreceedingElement(WorksheetPart worksheetPart)
    {
        List elements = new List()
        {
            typeof(Scenarios),
            typeof(ProtectedRanges),
            typeof(SheetProtection),
            typeof(SheetCalculationProperties),
            typeof(SheetData)
        };
    
        OpenXmlElement preceedingElement = null;
        foreach (var item in worksheetPart.Worksheet.ChildElements.Reverse())
        {
            if (elements.Contains(item.GetType()))
            {
                preceedingElement = item;
                break;
            }
        }
    
        return preceedingElement;
    }
    

提交回复
热议问题