2012-08-02 5 views
6

openxml을 사용하여 자동화 된 Excel 파일을 만들려고합니다. 내가 직면하고있는 한 가지 문제는 Excel 용 open xml 개체 모델로 내 개체 모델을 조정하는 것입니다. 나는 워크 시트에 대한 자식 요소를 추가하는 순서가 중요하다는 것을 깨닫는 시점에 도달해야합니다. 예를 들어OpenXml : 워크 시트 자식 요소 순서가 변경되어 파일이 손상됩니다.

는 :

workSheet.Append(sheetViews); 
workSheet.Append(columns); 
workSheet.Append(sheetData); 
workSheet.Append(mergeCells); 
workSheet.Append(drawing); 

위의 순서는 오류를 줄 doesnot.

그러나 다음

workSheet.Append(sheetViews); 
workSheet.Append(columns); 
workSheet.Append(sheetData); 
workSheet.Append(drawing); 
workSheet.Append(mergeCells); 

그래서 이것이 내가 원하는 워크 시트에 추가 할 때마다 나를 그리기 개체를 생성하지 않는 오류를

을 제공합니다. 어느 요소를 사용하기 전에 이러한 요소를 만들지 않으면 안됩니다.

문제를 제대로 이해했는지 알 수 있습니까? 어떤 Excel 파일을 열 수 있어야한다고 생각하기 때문에 필요한 경우 워크 시트에 새 하위 요소를 만들고 추가하십시오. 그러나 이제는 이러한 요소들이 추가되어야하는 순서가 깨질 수 있습니다.

감사합니다.

CT_Worksheet Schema Diagram

이유는 다음과 충돌한다 : 당신이mergeCells 전에 drawing을 가지고 있기 때문에

workSheet.Append(sheetViews); 
workSheet.Append(columns); 
workSheet.Append(sheetData); 
workSheet.Append(drawing); 
workSheet.Append(mergeCells); 

인가

답변

1

부모 개체에 속성 (예 : Worksheet.sheetViews)이 정의되어있는 모든 "싱글 톤"하위 항목에 대해 singleton 속성을 사용하고 "추가"를 사용하는 대신 새 개체를 할당한다는 사실을 알게되었습니다 주문이 올바른지 확인하십시오.

workSheet.Append(sheetViews); 
workSheet.Append(columns); 
workSheet.Append(sheetData); // bad idea(though it does work if the order is good) 
workSheet.Append(drawing); 
workSheet.Append(mergeCells); 

더 올바른 형식

...

workSheet.sheetViews=sheetViews; // order doesn't matter. 
workSheet.columns=columns; 
... 
0

은 조 Masilotti already explained으로, 순서는 스키마에 정의되어 있습니다.

OpenXML 라이브러리는 기본 XML 스키마에서 요구하는대로 직렬화 된 XML에서 하위 요소의 올바른 순서를 보장하지 않습니다. 응용 프로그램이 순서가 올바르지 않으면 XML을 성공적으로 구문 분석하지 못할 수 있습니다.

private T GetOrCreateWorksheetChildCollection<T>(Spreadsheet.Worksheet worksheet) 
    where T : OpenXmlCompositeElement, new() 
{ 
    T collection = worksheet.GetFirstChild<T>(); 
    if (collection == null) 
    { 
     collection = new T(); 
     if (!worksheet.HasChildren) 
     { 
      worksheet.AppendChild(collection); 
     } 
     else 
     { 
      // compute the positions of all child elements (existing + new collection) 
      List<int> schemaPositions = worksheet.ChildElements 
       .Select(e => _childElementNames.IndexOf(e.LocalName)).ToList(); 
      int collectionSchemaPos = _childElementNames.IndexOf(collection.LocalName); 
      schemaPositions.Add(collectionSchemaPos); 
      schemaPositions = schemaPositions.OrderBy(i => i).ToList(); 

      // now get the index where the position of the new child is 
      int index = schemaPositions.IndexOf(collectionSchemaPos); 

      // this is the index to insert the new element 
      worksheet.InsertAt(collection, index); 
     } 
    } 
    return collection; 
} 

// names and order of possible child elements according to the openXML schema 
private static readonly List<string> _childElementNames = new List<string>() { 
    "sheetPr", "dimension", "sheetViews", "sheetFormatPr", "cols", "sheetData", 
    "sheetCalcPr", "sheetProtection", "protectedRanges", "scenarios", "autoFilter", 
    "sortState", "dataConsolidate", "customSheetViews", "mergeCells", "phoneticPr", 
    "conditionalFormatting", "dataValidations", "hyperlinks", "printOptions", 
    "pageMargins", "pageSetup", "headerFooter", "rowBreaks", "colBreaks", 
    "customProperties", "cellWatches", "ignoredErrors", "smartTags", "drawing", 
    "drawingHF", "picture", "oleObjects", "controls", "webPublishItems", "tableParts", 
    "extLst" 
}; 

방법은 항상 결과 문서가 유효한지 보장, 올바른 위치에 새로운 자식 요소를 삽입 : 여기

내가 내 코드에서 사용하고 일반적인 솔루션입니다.

관련 문제