/** * Constructor * * @param mso a <code>MsoDrawingRecord</code> value * @param obj an <code>ObjRecord</code> value * @param dd the drawing data * @param sp an <code>int</code> value * @param ep an <code>int</code> value * @param f a <code>File</code> value * @param ws the workbook settings */ public Chart(MsoDrawingRecord mso, ObjRecord obj, DrawingData dd, int sp, int ep, File f, WorkbookSettings ws) { msoDrawingRecord = mso; objRecord = obj; startpos = sp; endpos = ep; file = f; workbookSettings = ws; // msoDrawingRecord is null if the entire sheet consists of just the // chart. In this case, as there is only one drawing on the page, // it isn't necessary to add to the drawing data record anyway if (msoDrawingRecord != null) { drawingData = dd; drawingData.addData(msoDrawingRecord.getRecord().getData()); drawingNumber = drawingData.getNumDrawings() - 1; } initialized = false; // Note: mso and obj values can be null if we are creating a chart // which takes up an entire worksheet. Check that both are null or both // not null though Assert.verify((mso != null && obj != null) || (mso == null && obj == null)); }
/** * Writes out the additional comment records * * @param outputFile the output file * @exception IOException */ public virtual void writeAdditionalRecords(File outputFile) { if (origin == Origin.READ) { outputFile.write(objRecord); if (mso != null) { outputFile.write(mso); } outputFile.write(txo); outputFile.write(text); if (formatting != null) { outputFile.write(formatting); } return; } // Create the obj record ObjRecord objrec = new ObjRecord(objectId, ObjRecord.EXCELNOTE); outputFile.write(objrec); // Create the mso data record. Write the text box record again, // although it is already included in the SpContainer ClientTextBox textBox = new ClientTextBox(); MsoDrawingRecord msod = new MsoDrawingRecord(textBox.getData()); outputFile.write(msod); TextobjectRecord txorec = new TextobjectRecord(getText()); outputFile.write(txorec); // Data for the first continue record byte[] textData = new byte[commentText.Length * 2 + 1]; textData[0] = 0x1; // unicode indicator StringHelper.getUnicodeBytes(commentText, textData, 1); //StringHelper.getBytes(commentText, textData, 1); ContinueRecord textContinue = new ContinueRecord(textData); outputFile.write(textContinue); // Data for the formatting runs byte[] frData = new byte[16]; // First txo run (the user) IntegerHelper.getTwoBytes(0, frData, 0); // index to the first character IntegerHelper.getTwoBytes(0, frData, 2); // index to the font(default) // Mandatory last txo run IntegerHelper.getTwoBytes(commentText.Length, frData, 8); IntegerHelper.getTwoBytes(0, frData, 10); // index to the font(default) ContinueRecord frContinue = new ContinueRecord(frData); outputFile.write(frContinue); }
/** * Indicates that at least one of the drawings has been omitted from * the worksheet * * @param mso the mso record * @param obj the obj record */ public void setDrawingsOmitted(MsoDrawingRecord mso, ObjRecord obj) { drawingsOmitted = true; if (obj != null) { maxobjectId = System.Math.Max(maxobjectId, obj.getObjectId()); } }
/** * Copy constructor used to copy drawings from read to write * * @param dgo the drawing group object * @param dg the drawing group */ protected Drawing2(DrawingGroupObject dgo, DrawingGroup dg) { Drawing2 d = (Drawing2)dgo; Assert.verify(d.origin == Origin.READ); msoDrawingRecord = d.msoDrawingRecord; initialized = false; origin = Origin.READ; drawingData = d.drawingData; drawingGroup = dg; drawingNumber = d.drawingNumber; drawingGroup.addDrawing(this); }
/** * Constructor used when reading images * * @param mso the drawing record * @param dd the drawing data for all drawings on this sheet * @param dg the drawing group */ public Drawing2(MsoDrawingRecord mso, DrawingData dd, DrawingGroup dg) { drawingGroup = dg; msoDrawingRecord = mso; drawingData = dd; initialized = false; origin = Origin.READ; // there is no drawing number associated with this drawing drawingData.addRawData(msoDrawingRecord.getData()); drawingGroup.addDrawing(this); Assert.verify(mso != null); initialize(); }
/** * Copy constructor used to copy drawings from read to write * * @param dgo the drawing group object * @param dg the drawing group * @param ws the workbook settings */ public ComboBox(DrawingGroupObject dgo, DrawingGroup dg, WorkbookSettings ws) { ComboBox d = (ComboBox)dgo; Assert.verify(d.origin == Origin.READ); msoDrawingRecord = d.msoDrawingRecord; objRecord = d.objRecord; initialized = false; origin = Origin.READ; drawingData = d.drawingData; drawingGroup = dg; drawingNumber = d.drawingNumber; drawingGroup.addDrawing(this); workbookSettings = ws; }
/** * Constructor used when reading images * * @param mso the drawing record * @param obj the object record * @param dd the drawing data for all drawings on this sheet * @param dg the drawing group * @param ws the workbook settings */ public CheckBox(MsoDrawingRecord mso, ObjRecord obj, DrawingData dd, DrawingGroup dg, WorkbookSettings ws) { drawingGroup = dg; msoDrawingRecord = mso; drawingData = dd; objRecord = obj; initialized = false; workbookSettings = ws; origin = Origin.READ; drawingData.addData(msoDrawingRecord.getData()); drawingNumber = drawingData.getNumDrawings() - 1; drawingGroup.addDrawing(this); Assert.verify(mso != null && obj != null); initialize(); }
/** * Constructor used when reading images * * @param mso the drawing record * @param obj the object record * @param dd the drawing data for all drawings on this sheet * @param dg the drawing group */ public Drawing(MsoDrawingRecord mso, ObjRecord obj, DrawingData dd, DrawingGroup dg, Sheet s) { drawingGroup = dg; msoDrawingRecord = mso; drawingData = dd; objRecord = obj; sheet = s; initialized = false; origin = Origin.READ; drawingData.addData(msoDrawingRecord.getData()); drawingNumber = drawingData.getNumDrawings() - 1; drawingGroup.addDrawing(this); Assert.verify(mso != null && obj != null); initialize(); }
/** * Copy constructor used to copy drawings from read to write * * @param dgo the drawing group object * @param dg the drawing group * @param ws the workbook settings */ public Button(DrawingGroupObject dgo, DrawingGroup dg, WorkbookSettings ws) { Button d = (Button)dgo; Assert.verify(d.origin == Origin.READ); msoDrawingRecord = d.msoDrawingRecord; objRecord = d.objRecord; initialized = false; origin = Origin.READ; drawingData = d.drawingData; drawingGroup = dg; drawingNumber = d.drawingNumber; drawingGroup.addDrawing(this); mso = d.mso; txo = d.txo; text = d.text; formatting = d.formatting; workbookSettings = ws; }
/** * Copy constructor used to copy drawings from read to write * * @param dgo the drawing group object * @param dg the drawing group * @param ws the workbook settings */ /*protected*/ public Comment(DrawingGroupObject dgo, DrawingGroup dg, WorkbookSettings ws) { Comment d = (Comment)dgo; Assert.verify(d.origin == Origin.READ); msoDrawingRecord = d.msoDrawingRecord; objRecord = d.objRecord; initialized = false; origin = Origin.READ; drawingData = d.drawingData; drawingGroup = dg; drawingNumber = d.drawingNumber; drawingGroup.addDrawing(this); mso = d.mso; txo = d.txo; text = d.text; formatting = d.formatting; note = d.note; width = d.width; height = d.height; workbookSettings = ws; }
/** * The drawing record * * @param d the drawing record */ public void addMso(MsoDrawingRecord d) { mso = d; drawingData.addRawData(mso.getData()); }
/** * Writes out the MsoDrawing records and Obj records for each image * and chart on the sheet * * @param outputFile the output file * @exception IOException */ public void write(File outputFile) { // If there are no drawings or charts on this sheet then exit if (drawings.Count == 0 && charts.Length == 0) { return; } // See if any drawing has been modified bool modified = drawingsModified; int numImages = drawings.Count; foreach (DrawingGroupObject d in drawings) { if (d.getOrigin() != Origin.READ) { modified = true; } } // If the drawing order has been muddled at all, then we'll need // to regenerate the Escher drawing data if (numImages > 0 && !modified) { DrawingGroupObject d2 = (DrawingGroupObject)drawings[0]; if (!d2.isFirst()) { modified = true; } } // Check to see if this sheet consists of just a single chart. If so // there is no MsoDrawingRecord, so write out the data and exit if (numImages == 0 && charts.Length == 1 && charts[0].getMsoDrawingRecord() == null) { modified = false; // this sheet has not been modified } // If no drawing has been modified, then simply write them straight out // again and exit if (!modified) { writeUnmodified(outputFile); return; } object[] spContainerData = new object[numImages + charts.Length]; int length = 0; EscherContainer firstSpContainer = null; // Get all the spContainer byte data from the drawings // and store in an array for (int i = 0; i < numImages; i++) { DrawingGroupObject drawing = (DrawingGroupObject)drawings[i]; EscherContainer spc = drawing.getSpContainer(); if (spc != null) { byte[] data = spc.getData(); spContainerData[i] = data; if (i == 0) { firstSpContainer = spc; } else { length += data.Length; } } } // Get all the spContainer bytes from the charts and add to the array for (int i = 0; i < charts.Length; i++) { EscherContainer spContainer = charts[i].getSpContainer(); byte[] data = spContainer.getBytes(); //use getBytes instead of getData data = spContainer.setHeaderData(data); spContainerData[i + numImages] = data; if (i == 0 && numImages == 0) { firstSpContainer = spContainer; } else { length += data.Length; } } // Put the generalised stuff around the first item DgContainer dgContainer = new DgContainer(); Dg dg = new Dg(numImages + charts.Length); dgContainer.add(dg); SpgrContainer spgrContainer = new SpgrContainer(); SpContainer _spContainer = new SpContainer(); Spgr spgr = new Spgr(); _spContainer.add(spgr); Sp sp = new Sp(ShapeType.MIN, 1024, 5); _spContainer.add(sp); spgrContainer.add(_spContainer); spgrContainer.add(firstSpContainer); dgContainer.add(spgrContainer); byte[] firstMsoData = dgContainer.getData(); // Adjust the length of the DgContainer int len = IntegerHelper.getInt(firstMsoData[4], firstMsoData[5], firstMsoData[6], firstMsoData[7]); IntegerHelper.getFourBytes(len + length, firstMsoData, 4); // Adjust the length of the SpgrContainer len = IntegerHelper.getInt(firstMsoData[28], firstMsoData[29], firstMsoData[30], firstMsoData[31]); IntegerHelper.getFourBytes(len + length, firstMsoData, 28); // Now write out each MsoDrawing record // First MsoRecord // test hack for form objects, to remove the ClientTextBox record // from the end of the SpContainer if (numImages > 0 && ((DrawingGroupObject)drawings[0]).isFormObject()) { byte[] msodata2 = new byte[firstMsoData.Length - 8]; System.Array.Copy(firstMsoData, 0, msodata2, 0, msodata2.Length); firstMsoData = msodata2; } MsoDrawingRecord msoDrawingRecord = new MsoDrawingRecord(firstMsoData); outputFile.write(msoDrawingRecord); if (numImages > 0) { DrawingGroupObject firstDrawing = (DrawingGroupObject)drawings[0]; firstDrawing.writeAdditionalRecords(outputFile); } else { // first image is a chart Chart chart = charts[0]; ObjRecord objRecord = chart.getObjRecord(); outputFile.write(objRecord); outputFile.write(chart); } // Now do all the others for (int i = 1; i < spContainerData.Length; i++) { byte[] bytes = (byte[])spContainerData[i]; // test hack for form objects, to remove the ClientTextBox record // from the end of the SpContainer if (i < numImages && ((DrawingGroupObject)drawings[i]).isFormObject()) { byte[] bytes2 = new byte[bytes.Length - 8]; System.Array.Copy(bytes, 0, bytes2, 0, bytes2.Length); bytes = bytes2; } msoDrawingRecord = new MsoDrawingRecord(bytes); outputFile.write(msoDrawingRecord); if (i < numImages) { // Write anything else the object needs DrawingGroupObject d = (DrawingGroupObject)drawings[i]; d.writeAdditionalRecords(outputFile); } else { Chart chart = charts[i - numImages]; ObjRecord objRecord = chart.getObjRecord(); outputFile.write(objRecord); outputFile.write(chart); } } // Write any tail records that need to be written foreach (DrawingGroupObject dgo2 in drawings) { dgo2.writeTailRecords(outputFile); } }
/** * Writes out the drawings and the charts if nothing has been modified * * @param outputFile the output file * @exception IOException */ private void writeUnmodified(File outputFile) { if (charts.Length == 0 && drawings.Count == 0) { // No drawings or charts return; } else if (charts.Length == 0 && drawings.Count != 0) { // If there are no charts, then write out the drawings and return foreach (DrawingGroupObject d in drawings) { outputFile.write(d.getMsoDrawingRecord()); d.writeAdditionalRecords(outputFile); } foreach (DrawingGroupObject d in drawings) { d.writeTailRecords(outputFile); } return; } else if (drawings.Count == 0 && charts.Length != 0) { // If there are no drawings, then write out the charts and return Chart curChart = null; for (int i = 0; i < charts.Length; i++) { curChart = charts[i]; if (curChart.getMsoDrawingRecord() != null) { outputFile.write(curChart.getMsoDrawingRecord()); } if (curChart.getObjRecord() != null) { outputFile.write(curChart.getObjRecord()); } outputFile.write(curChart); } return; } // There are both charts and drawings - the output // drawing group records will need // to be re-jigged in order to write the drawings out first, then the // charts int numDrawings = drawings.Count; int length = 0; EscherContainer[] spContainers = new EscherContainer[numDrawings + charts.Length]; bool[] isFormobject = new bool[numDrawings + charts.Length]; for (int i = 0; i < numDrawings; i++) { DrawingGroupObject d = (DrawingGroupObject)drawings[i]; spContainers[i] = d.getSpContainer(); if (i > 0) { length += spContainers[i].getLength(); } if (d.isFormObject()) { isFormobject[i] = true; } } for (int i = 0; i < charts.Length; i++) { spContainers[i + numDrawings] = charts[i].getSpContainer(); length += spContainers[i + numDrawings].getLength(); } // Put the generalised stuff around the first item DgContainer dgContainer = new DgContainer(); Dg dg = new Dg(numDrawings + charts.Length); dgContainer.add(dg); SpgrContainer spgrContainer = new SpgrContainer(); SpContainer spContainer = new SpContainer(); Spgr spgr = new Spgr(); spContainer.add(spgr); Sp sp = new Sp(ShapeType.MIN, 1024, 5); spContainer.add(sp); spgrContainer.add(spContainer); spgrContainer.add(spContainers[0]); dgContainer.add(spgrContainer); byte[] firstMsoData = dgContainer.getData(); // Adjust the length of the DgContainer int len = IntegerHelper.getInt(firstMsoData[4], firstMsoData[5], firstMsoData[6], firstMsoData[7]); IntegerHelper.getFourBytes(len + length, firstMsoData, 4); // Adjust the length of the SpgrContainer len = IntegerHelper.getInt(firstMsoData[28], firstMsoData[29], firstMsoData[30], firstMsoData[31]); IntegerHelper.getFourBytes(len + length, firstMsoData, 28); // Now write out each MsoDrawing record and object record // Hack to remove the last eight bytes (text box escher record) // from the container if (isFormobject[0] == true) { byte[] cbytes = new byte[firstMsoData.Length - 8]; System.Array.Copy(firstMsoData, 0, cbytes, 0, cbytes.Length); firstMsoData = cbytes; } // First MsoRecord MsoDrawingRecord msoDrawingRecord = new MsoDrawingRecord(firstMsoData); outputFile.write(msoDrawingRecord); DrawingGroupObject dgo = (DrawingGroupObject)drawings[0]; dgo.writeAdditionalRecords(outputFile); // Now do all the others for (int i = 1; i < spContainers.Length; i++) { byte[] bytes = spContainers[i].getBytes(); byte[] bytes2 = spContainers[i].setHeaderData(bytes); // Hack to remove the last eight bytes (text box escher record) // from the container if (isFormobject[i] == true) { byte[] cbytes = new byte[bytes2.Length - 8]; System.Array.Copy(bytes2, 0, cbytes, 0, cbytes.Length); bytes2 = cbytes; } msoDrawingRecord = new MsoDrawingRecord(bytes2); outputFile.write(msoDrawingRecord); if (i < numDrawings) { dgo = (DrawingGroupObject)drawings[i]; dgo.writeAdditionalRecords(outputFile); } else { Chart chart = charts[i - numDrawings]; ObjRecord objRecord = chart.getObjRecord(); outputFile.write(objRecord); outputFile.write(chart); } } // Write any tail records that need to be written foreach (DrawingGroupObject dgo2 in drawings) { dgo2.writeTailRecords(outputFile); } }