/// <summary> /// Creates the patriarch. /// </summary> /// <param name="sheet">the sheet this patriarch is stored in.</param> /// <param name="boundAggregate">The bound aggregate.</param> public HSSFPatriarch(HSSFSheet sheet, EscherAggregate boundAggregate) { _boundAggregate = boundAggregate; _sheet = sheet; _mainSpgrContainer = _boundAggregate.GetEscherContainer().ChildContainers[0]; EscherContainerRecord spContainer = (EscherContainerRecord)_boundAggregate.GetEscherContainer() .ChildContainers[0].GetChild(0); _spgrRecord = (EscherSpgrRecord)spContainer.GetChildById(EscherSpgrRecord.RECORD_ID); BuildShapeTree(); }
public static HSSFPatriarch CreateTestPatriarch(HSSFSheet sheet, EscherAggregate agg) { return new HSSFPatriarch(sheet, agg); }
/** * Collapses the drawing records into an aggregate. * read Drawing, Obj, TxtObj, Note and Continue records into single byte array, * create Escher tree from byte array, create map <EscherRecord, Record> * * @param records - list of all records inside sheet * @param locFirstDrawingRecord - location of the first DrawingRecord inside sheet * @return new EscherAggregate create from all aggregated records which belong to drawing layer */ public static EscherAggregate CreateAggregate(List<RecordBase> records, int locFirstDrawingRecord) { // Keep track of any shape records Created so we can match them back to the object id's. // Textbox objects are also treated as shape objects. List<EscherRecord> shapeRecords = new List<EscherRecord>(); IEscherRecordFactory recordFactory = new CustomEscherRecordFactory(shapeRecords); // Create one big buffer MemoryStream stream = new MemoryStream(); EscherAggregate agg = new EscherAggregate(false); int loc = locFirstDrawingRecord; while (loc + 1 < records.Count && (IsDrawingLayerRecord(GetSid(records, loc)))) { try { if (!(GetSid(records, loc) == DrawingRecord.sid || GetSid(records, loc) == ContinueRecord.sid)) { loc++; continue; } if (GetSid(records, loc) == DrawingRecord.sid) { byte[] data = ((DrawingRecord)records[loc]).Data; stream.Write(data, 0, data.Length); } else { byte[] data = ((ContinueRecord)records[loc]).Data; stream.Write(data, 0, data.Length); } } catch (IOException e) { throw new RuntimeException("Couldn't get data from drawing/continue records", e); } loc++; } // Decode the shapes // agg.escherRecords = new ArrayList(); int pos = 0; byte[] buffer = stream.ToArray(); while (pos < buffer.Length) { EscherRecord r = recordFactory.CreateRecord(buffer, pos); int bytesRead = r.FillFields(buffer, pos, recordFactory); agg.AddEscherRecord(r); pos += bytesRead; } // Associate the object records with the shapes loc = locFirstDrawingRecord + 1; int shapeIndex = 0; while (loc < records.Count && IsDrawingLayerRecord(GetSid(records, loc))) { if (!IsObjectRecord(records, loc)) { loc++; continue; } Record objRecord = (Record)records[loc]; agg.shapeToObj[shapeRecords[shapeIndex++]] = objRecord; loc++; } // any NoteRecords that follow the drawing block must be aggregated and and saved in the tailRec collection //put noterecord into tailsRec while (loc < records.Count) { if (GetSid(records, loc) == NoteRecord.sid) { NoteRecord r = (NoteRecord)records[(loc)]; agg.tailRec[r.ShapeId] = r; } else { break; } loc++; } int locLastDrawingRecord = loc; //records.SubList(locFirstDrawingRecord, locLastDrawingRecord).Clear(); records.RemoveRange(locFirstDrawingRecord, locLastDrawingRecord - locFirstDrawingRecord); records.Insert(locFirstDrawingRecord, agg); return agg; }
public void TestSerialize() { EscherContainerRecord container1 = new EscherContainerRecord(); EscherContainerRecord spContainer1 = new EscherContainerRecord(); EscherContainerRecord spContainer2 = new EscherContainerRecord(); EscherContainerRecord spContainer3 = new EscherContainerRecord(); EscherSpRecord sp1 = new EscherSpRecord(); EscherSpRecord sp2 = new EscherSpRecord(); EscherSpRecord sp3 = new EscherSpRecord(); EscherClientDataRecord d2 = new EscherClientDataRecord(); EscherClientDataRecord d3 = new EscherClientDataRecord(); container1.Options = ((short)0x000F); spContainer1.Options = ((short)0x000F); spContainer1.RecordId = (EscherContainerRecord.SP_CONTAINER); spContainer2.Options = ((short)0x000F); spContainer2.RecordId = (EscherContainerRecord.SP_CONTAINER); spContainer3.Options = ((short)0x000F); spContainer3.RecordId = (EscherContainerRecord.SP_CONTAINER); d2.RecordId = (EscherClientDataRecord.RECORD_ID); d2.RemainingData = (new byte[0]); d3.RecordId = (EscherClientDataRecord.RECORD_ID); d3.RemainingData = (new byte[0]); container1.AddChildRecord(spContainer1); container1.AddChildRecord(spContainer2); container1.AddChildRecord(spContainer3); spContainer1.AddChildRecord(sp1); spContainer2.AddChildRecord(sp2); spContainer3.AddChildRecord(sp3); spContainer2.AddChildRecord(d2); spContainer3.AddChildRecord(d3); EscherAggregate aggregate = new EscherAggregate(null); aggregate.AddEscherRecord(container1); aggregate.AssoicateShapeToObjRecord(d2, new ObjRecord()); aggregate.AssoicateShapeToObjRecord(d3, new ObjRecord()); byte[] data = new byte[112]; int bytesWritten = aggregate.Serialize(0, data); Assert.AreEqual(112, bytesWritten); Assert.AreEqual("[EC, 00, 40, 00, 0F, 00, 00, 00, 58, 00, 00, 00, 0F, 00, 04, F0, 10, 00, 00, 00, 00, 00, 0A, F0, 08, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0F, 00, 04, F0, 18, 00, 00, 00, 00, 00, 0A, F0, 08, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 11, F0, 00, 00, 00, 00, 5D, 00, 00, 00, EC, 00, 20, 00, 0F, 00, 04, F0, 18, 00, 00, 00, 00, 00, 0A, F0, 08, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 11, F0, 00, 00, 00, 00, 5D, 00, 00, 00, ]", HexDump.ToHex(data)); }
/// <summary> /// Finds the DrawingRecord for our sheet, and attaches it to the DrawingManager (which knows about /// the overall DrawingGroup for our workbook). /// If requested, will Create a new DrawRecord if none currently exist /// </summary> /// <param name="drawingManager">The DrawingManager2 for our workbook</param> /// <param name="CreateIfMissing">Should one be Created if missing?</param> /// <returns>location of EscherAggregate record. if no EscherAggregate record is found return -1</returns> public int AggregateDrawingRecords(DrawingManager2 drawingManager, bool CreateIfMissing) { int loc = FindFirstRecordLocBySid(DrawingRecord.sid); bool noDrawingRecordsFound = (loc == -1); if (noDrawingRecordsFound) { if (!CreateIfMissing) { // None found, and not allowed to Add in return -1; } EscherAggregate aggregate = new EscherAggregate(true); loc = FindFirstRecordLocBySid(EscherAggregate.sid); if (loc == -1) { loc = FindFirstRecordLocBySid(WindowTwoRecord.sid); } else { Records.RemoveAt(loc); } Records.Insert(loc, aggregate); return loc; } EscherAggregate.CreateAggregate(records, loc); return loc; }
/** * Finds the DrawingRecord for our sheet, and * attaches it to the DrawingManager (which knows about * the overall DrawingGroup for our workbook). * If requested, will Create a new DrawRecord * if none currently exist * @param drawingManager The DrawingManager2 for our workbook * @param CreateIfMissing Should one be Created if missing? */ public int AggregateDrawingRecords(DrawingManager2 drawingManager, bool CreateIfMissing) { int loc = FindFirstRecordLocBySid(DrawingRecord.sid); bool noDrawingRecordsFound = (loc == -1); if (noDrawingRecordsFound) { if (!CreateIfMissing) { // None found, and not allowed to Add in return -1; } EscherAggregate aggregate = new EscherAggregate(drawingManager); loc = FindFirstRecordLocBySid(EscherAggregate.sid); if (loc == -1) { loc = FindFirstRecordLocBySid(WindowTwoRecord.sid); } else { Records.RemoveAt(loc); } Records.Insert(loc, aggregate); return loc; } else { IList records = Records; EscherAggregate r = EscherAggregate.CreateAggregate(records, loc, drawingManager); int startloc = loc; while (loc + 1 < records.Count && records[loc] is DrawingRecord && records[loc + 1] is ObjRecord) { loc += 2; } int endloc = loc - 1; for (int i = 0; i < (endloc - startloc + 1); i++) records.RemoveAt(startloc); records.Insert(startloc, r); return startloc; } }
/// <summary> /// Creates the patriarch. /// </summary> /// <param name="sheet">the sheet this patriarch is stored in.</param> /// <param name="boundAggregate">The bound aggregate.</param> public HSSFPatriarch(HSSFSheet sheet, EscherAggregate boundAggregate) { this.boundAggregate = boundAggregate; this.sheet = sheet; }
/** * build shape tree from escher container * @param container root escher container from which escher records must be taken * @param agg - EscherAggregate * @param out - shape container to which shapes must be added * @param root - node to create HSSFObjectData shapes */ public static void CreateShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out1, DirectoryNode root) { if (container.RecordId == EscherContainerRecord.SPGR_CONTAINER) { ObjRecord obj = null; EscherClientDataRecord clientData = (EscherClientDataRecord)((EscherContainerRecord)container.GetChild(0)).GetChildById(EscherClientDataRecord.RECORD_ID); if (null != clientData) { obj = (ObjRecord)agg.GetShapeToObjMapping()[clientData]; } HSSFShapeGroup group = new HSSFShapeGroup(container, obj); IList<EscherContainerRecord> children = container.ChildContainers; // skip the first child record, it is group descriptor for (int i = 0; i < children.Count; i++) { EscherContainerRecord spContainer = children[(i)]; if (i != 0) { CreateShapeTree(spContainer, agg, group, root); } } out1.AddShape(group); } else if (container.RecordId == EscherContainerRecord.SP_CONTAINER) { Dictionary<EscherRecord, Record.Record> shapeToObj = agg.GetShapeToObjMapping(); ObjRecord objRecord = null; TextObjectRecord txtRecord = null; foreach (EscherRecord record in container.ChildRecords) { switch (record.RecordId) { case EscherClientDataRecord.RECORD_ID: objRecord = (ObjRecord)shapeToObj[(record)]; break; case EscherTextboxRecord.RECORD_ID: txtRecord = (TextObjectRecord)shapeToObj[(record)]; break; } } if (IsEmbeddedObject(objRecord)) { HSSFObjectData objectData = new HSSFObjectData(container, objRecord, root); out1.AddShape(objectData); return; } CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord)objRecord.SubRecords[0]; HSSFShape shape; switch (cmo.ObjectType) { case CommonObjectType.Picture: shape = new HSSFPicture(container, objRecord); break; case CommonObjectType.Rectangle: shape = new HSSFSimpleShape(container, objRecord, txtRecord); break; case CommonObjectType.Line: shape = new HSSFSimpleShape(container, objRecord); break; case CommonObjectType.ComboBox: shape = new HSSFCombobox(container, objRecord); break; case CommonObjectType.MicrosoftOfficeDrawing: EscherOptRecord optRecord = (EscherOptRecord)container.GetChildById(EscherOptRecord.RECORD_ID); EscherProperty property = optRecord.Lookup(EscherProperties.GEOMETRY__VERTICES); if (null != property) { shape = new HSSFPolygon(container, objRecord, txtRecord); } else { shape = new HSSFSimpleShape(container, objRecord, txtRecord); } break; case CommonObjectType.Text: shape = new HSSFTextbox(container, objRecord, txtRecord); break; case CommonObjectType.Comment: shape = new HSSFComment(container, objRecord, txtRecord, agg.GetNoteRecordByObj(objRecord)); break; default: shape = new HSSFSimpleShape(container, objRecord, txtRecord); break; } out1.AddShape(shape); } }
/** * Collapses the drawing records into an aggregate. */ public static EscherAggregate CreateAggregate(IList records, int locFirstDrawingRecord, DrawingManager2 drawingManager) { // Keep track of any shape records Created so we can match them back to the object id's. // Textbox objects are also treated as shape objects. IList shapeRecords = new ArrayList(); EscherRecordFactory recordFactory = new CustomEscherRecordFactory(ref shapeRecords); // Calculate the size of the buffer EscherAggregate agg = new EscherAggregate(drawingManager); int loc = locFirstDrawingRecord; int dataSize = 0; while (loc + 1 < records.Count && GetSid(records, loc) == DrawingRecord.sid && IsObjectRecord(records, loc + 1)) { dataSize += ((DrawingRecord)records[loc]).Data.Length; loc += 2; } // Create one big buffer byte[] buffer = new byte[dataSize]; int offset = 0; loc = locFirstDrawingRecord; while (loc + 1 < records.Count && GetSid(records, loc) == DrawingRecord.sid && IsObjectRecord(records, loc + 1)) { DrawingRecord drawingRecord = (DrawingRecord)records[loc]; Array.Copy(drawingRecord.Data, 0, buffer, offset, drawingRecord.Data.Length); offset += drawingRecord.Data.Length; loc += 2; } // Decode the shapes // agg.escherRecords = new ArrayList(); int pos = 0; while (pos < dataSize) { EscherRecord r = recordFactory.CreateRecord(buffer, pos); int bytesRead = r.FillFields(buffer, pos, recordFactory); agg.AddEscherRecord(r); pos += bytesRead; } // Associate the object records with the shapes loc = locFirstDrawingRecord; int shapeIndex = 0; agg.shapeToObj = new Hashtable(); while (loc + 1 < records.Count && GetSid(records, loc) == DrawingRecord.sid && IsObjectRecord(records, loc + 1)) { Record objRecord = (Record)records[loc + 1]; agg.shapeToObj[shapeRecords[shapeIndex++]]= objRecord; loc += 2; } return agg; }
/** * Collapses the drawing records into an aggregate. */ public static EscherAggregate CreateAggregate(IList records, int locFirstDrawingRecord, DrawingManager2 drawingManager) { // Keep track of any shape records Created so we can match them back to the object id's. // Textbox objects are also treated as shape objects. IList shapeRecords = new ArrayList(); EscherRecordFactory recordFactory = new CustomEscherRecordFactory(ref shapeRecords); // Calculate the size of the buffer EscherAggregate agg = new EscherAggregate(drawingManager); int loc = locFirstDrawingRecord; int dataSize = 0; while (loc + 1 < records.Count && GetSid(records, loc) == DrawingRecord.sid && IsObjectRecord(records, loc + 1)) { dataSize += ((DrawingRecord)records[loc]).Data.Length; loc += 2; } // Create one big buffer byte[] buffer = new byte[dataSize]; int offset = 0; loc = locFirstDrawingRecord; while (loc + 1 < records.Count && GetSid(records, loc) == DrawingRecord.sid && IsObjectRecord(records, loc + 1)) { DrawingRecord drawingRecord = (DrawingRecord)records[loc]; Array.Copy(drawingRecord.Data, 0, buffer, offset, drawingRecord.Data.Length); offset += drawingRecord.Data.Length; loc += 2; } // Decode the shapes // agg.escherRecords = new ArrayList(); int pos = 0; while (pos < dataSize) { EscherRecord r = recordFactory.CreateRecord(buffer, pos); int bytesRead = r.FillFields(buffer, pos, recordFactory); agg.AddEscherRecord(r); pos += bytesRead; } // Associate the object records with the shapes loc = locFirstDrawingRecord; int shapeIndex = 0; agg.shapeToObj = new Hashtable(); while (loc + 1 < records.Count && GetSid(records, loc) == DrawingRecord.sid && IsObjectRecord(records, loc + 1)) { Record objRecord = (Record)records[loc + 1]; agg.shapeToObj[shapeRecords[shapeIndex++]] = objRecord; loc += 2; } return(agg); }