public void ClipRect(int x, int y, int width, int height) { if (Logger.Check(POILogger.WARN)) { Logger.Log(POILogger.WARN, "clipRect not supported"); } }
public IRichTextString CreateRichTextString(string text) { logger.Log(POILogger.INFO, "SXSSF doesn't support Rich Text Strings, any formatting information will be lost"); return(new XSSFRichTextString(text)); }
protected bool ProcessCell(ICell cell, XmlElement tableCellElement, int normalWidthPx, int maxSpannedWidthPx, float normalHeightPt) { ICellStyle cellStyle = cell.CellStyle as ICellStyle; string value; switch (cell.CellType) { case CellType.String: // XXX: enrich value = cell.RichStringCellValue.String; break; case CellType.Formula: switch (cell.CachedFormulaResultType) { case CellType.String: IRichTextString str = cell.RichStringCellValue; if (str != null && str.Length > 0) { value = (str.String); } else { value = string.Empty; } break; case CellType.Numeric: ICellStyle style = cellStyle; if (style == null) { value = cell.NumericCellValue.ToString(); } else { value = (_formatter.FormatRawCellContents(cell.NumericCellValue, style.DataFormat, style.GetDataFormatString())); } break; case CellType.Boolean: value = cell.BooleanCellValue.ToString(); break; case CellType.Error: value = ErrorEval.GetText(cell.ErrorCellValue); break; default: logger.Log(POILogger.WARN, "Unexpected cell cachedFormulaResultType (" + cell.CachedFormulaResultType.ToString() + ")"); value = string.Empty; break; } break; case CellType.Blank: value = string.Empty; break; case CellType.Numeric: value = _formatter.FormatCellValue(cell); break; case CellType.Boolean: value = cell.BooleanCellValue.ToString(); break; case CellType.Error: value = ErrorEval.GetText(cell.ErrorCellValue); break; default: logger.Log(POILogger.WARN, "Unexpected cell type (" + cell.CellType.ToString() + ")"); return(true); } bool noText = string.IsNullOrEmpty(value); bool wrapInDivs = !noText && UseDivsToSpan && !cellStyle.WrapText; short cellStyleIndex = cellStyle.Index; if (cellStyleIndex != 0) { IWorkbook workbook = cell.Row.Sheet.Workbook as IWorkbook; string mainCssClass = GetStyleClassName(workbook, cellStyle); if (wrapInDivs) { tableCellElement.SetAttribute("class", mainCssClass + " " + cssClassContainerCell); } else { tableCellElement.SetAttribute("class", mainCssClass); } if (noText) { /* * if cell style is defined (like borders, etc.) but cell text * is empty, add " " to output, so browser won't collapse * and ignore cell */ value = "\u00A0"; //“ ”全角空格 } } if (OutputLeadingSpacesAsNonBreaking && value.StartsWith(" ")) { StringBuilder builder = new StringBuilder(); for (int c = 0; c < value.Length; c++) { if (value[c] != ' ') { break; } builder.Append('\u00a0'); } if (value.Length != builder.Length) { builder.Append(value.Substring(builder.Length)); } value = builder.ToString(); } XmlText text = htmlDocumentFacade.CreateText(value); if (wrapInDivs) { XmlElement outerDiv = htmlDocumentFacade.CreateBlock(); outerDiv.SetAttribute("class", this.cssClassContainerDiv); XmlElement innerDiv = htmlDocumentFacade.CreateBlock(); StringBuilder innerDivStyle = new StringBuilder(); innerDivStyle.Append("position:absolute;min-width:"); innerDivStyle.Append(normalWidthPx); innerDivStyle.Append("px;"); if (maxSpannedWidthPx != int.MaxValue) { innerDivStyle.Append("max-width:"); innerDivStyle.Append(maxSpannedWidthPx); innerDivStyle.Append("px;"); } innerDivStyle.Append("overflow:hidden;max-height:"); innerDivStyle.Append(normalHeightPt); innerDivStyle.Append("pt;white-space:nowrap;"); ExcelToHtmlUtils.AppendAlign(innerDivStyle, cellStyle.Alignment); htmlDocumentFacade.AddStyleClass(outerDiv, "d", innerDivStyle.ToString()); innerDiv.AppendChild(text); outerDiv.AppendChild(innerDiv); tableCellElement.AppendChild(outerDiv); } else { tableCellElement.AppendChild(text); } return(string.IsNullOrEmpty(value) && cellStyleIndex == 0); }
// visibility raised for testing /* package */ public ValueEval EvaluateFormula(OperationEvaluationContext ec, Ptg[] ptgs) { String dbgIndentStr = ""; // always init. to non-null just for defensive avoiding NPE if (dbgEvaluationOutputForNextEval) { // first evaluation call when ouput is desired, so iit. this evaluator instance dbgEvaluationOutputIndent = 1; dbgEvaluationOutputForNextEval = false; } if (dbgEvaluationOutputIndent > 0) { // init. indent string to needed spaces (create as substring vom very long space-only string; // limit indendation for deep recursions) dbgIndentStr = " "; dbgIndentStr = dbgIndentStr.Substring(0, Math.Min(dbgIndentStr.Length, dbgEvaluationOutputIndent * 2)); EVAL_LOG.Log(POILogger.WARN, dbgIndentStr + "- evaluateFormula('" + ec.GetRefEvaluatorForCurrentSheet().SheetNameRange + "'/" + new CellReference(ec.RowIndex, ec.ColumnIndex).FormatAsString() + "): " + Arrays.ToString(ptgs).Replace("\\Qorg.apache.poi.ss.formula.ptg.\\E", "")); dbgEvaluationOutputIndent++; } Stack <ValueEval> stack = new Stack <ValueEval>(); for (int i = 0, iSize = ptgs.Length; i < iSize; i++) { // since we don't know how To handle these yet :( Ptg ptg = ptgs[i]; if (dbgEvaluationOutputIndent > 0) { EVAL_LOG.Log(POILogger.INFO, dbgIndentStr + " * ptg " + i + ": " + ptg.ToString()); } if (ptg is AttrPtg) { AttrPtg attrPtg = (AttrPtg)ptg; if (attrPtg.IsSum) { // Excel prefers To encode 'SUM()' as a tAttr Token, but this evaluator // expects the equivalent function Token //byte nArgs = 1; // tAttrSum always Has 1 parameter ptg = FuncVarPtg.SUM;//.Create("SUM", nArgs); } if (attrPtg.IsOptimizedChoose) { ValueEval arg0 = stack.Pop(); int[] jumpTable = attrPtg.JumpTable; int dist; int nChoices = jumpTable.Length; try { int switchIndex = Choose.EvaluateFirstArg(arg0, ec.RowIndex, ec.ColumnIndex); if (switchIndex < 1 || switchIndex > nChoices) { stack.Push(ErrorEval.VALUE_INVALID); dist = attrPtg.ChooseFuncOffset + 4; // +4 for tFuncFar(CHOOSE) } else { dist = jumpTable[switchIndex - 1]; } } catch (EvaluationException e) { stack.Push(e.GetErrorEval()); dist = attrPtg.ChooseFuncOffset + 4; // +4 for tFuncFar(CHOOSE) } // Encoded dist for tAttrChoose includes size of jump table, but // countTokensToBeSkipped() does not (it counts whole tokens). dist -= nChoices * 2 + 2; // subtract jump table size i += CountTokensToBeSkipped(ptgs, i, dist); continue; } if (attrPtg.IsOptimizedIf) { ValueEval arg0 = stack.Pop(); bool evaluatedPredicate; try { evaluatedPredicate = IfFunc.EvaluateFirstArg(arg0, ec.RowIndex, ec.ColumnIndex); } catch (EvaluationException e) { stack.Push(e.GetErrorEval()); int dist = attrPtg.Data; i += CountTokensToBeSkipped(ptgs, i, dist); attrPtg = (AttrPtg)ptgs[i]; dist = attrPtg.Data + 1; i += CountTokensToBeSkipped(ptgs, i, dist); continue; } if (evaluatedPredicate) { // nothing to skip - true param folows } else { int dist = attrPtg.Data; i += CountTokensToBeSkipped(ptgs, i, dist); Ptg nextPtg = ptgs[i + 1]; if (ptgs[i] is AttrPtg && nextPtg is FuncVarPtg && // in order to verify that there is no third param, we need to check // if we really have the IF next or some other FuncVarPtg as third param, e.g. ROW()/COLUMN()! ((FuncVarPtg)nextPtg).FunctionIndex == FunctionMetadataRegistry.FUNCTION_INDEX_IF) { // this is an if statement without a false param (as opposed to MissingArgPtg as the false param) i++; stack.Push(BoolEval.FALSE); } } continue; } if (attrPtg.IsSkip) { int dist = attrPtg.Data + 1; i += CountTokensToBeSkipped(ptgs, i, dist); if (stack.Peek() == MissingArgEval.instance) { stack.Pop(); stack.Push(BlankEval.instance); } continue; } } if (ptg is ControlPtg) { // skip Parentheses, Attr, etc continue; } if (ptg is MemFuncPtg || ptg is MemAreaPtg) { // can ignore, rest of Tokens for this expression are in OK RPN order continue; } if (ptg is MemErrPtg) { continue; } ValueEval opResult; if (ptg is OperationPtg) { OperationPtg optg = (OperationPtg)ptg; if (optg is UnionPtg) { continue; } int numops = optg.NumberOfOperands; ValueEval[] ops = new ValueEval[numops]; // storing the ops in reverse order since they are popping for (int j = numops - 1; j >= 0; j--) { ValueEval p = (ValueEval)stack.Pop(); ops[j] = p; } // logDebug("Invoke " + operation + " (nAgs=" + numops + ")"); opResult = OperationEvaluatorFactory.Evaluate(optg, ops, ec); } else { opResult = GetEvalForPtg(ptg, ec); } if (opResult == null) { throw new Exception("Evaluation result must not be null"); } // logDebug("push " + opResult); stack.Push(opResult); if (dbgEvaluationOutputIndent > 0) { EVAL_LOG.Log(POILogger.INFO, dbgIndentStr + " = " + opResult.ToString()); } } ValueEval value = ((ValueEval)stack.Pop()); if (stack.Count != 0) { throw new InvalidOperationException("evaluation stack not empty"); } ValueEval result = DereferenceResult(value, ec.RowIndex, ec.ColumnIndex); if (dbgEvaluationOutputIndent > 0) { EVAL_LOG.Log(POILogger.INFO, dbgIndentStr + "finshed eval of " + new CellReference(ec.RowIndex, ec.ColumnIndex).FormatAsString() + ": " + result.ToString()); dbgEvaluationOutputIndent--; if (dbgEvaluationOutputIndent == 1) { // this evaluation is done, reset indent to stop logging dbgEvaluationOutputIndent = -1; } } // if return(result); }
/** * Parse the relationship part and add all relationship in this collection. * * @param relPart * The package part to parse. * @throws InvalidFormatException * Throws if the relationship part is invalid. */ private void ParseRelationshipsPart(PackagePart relPart) { try { logger.Log(POILogger.DEBUG, "Parsing relationship: " + relPart.PartName); XPathDocument xmlRelationshipsDoc = DocumentHelper.ReadDocument(relPart.GetInputStream()); // Check OPC compliance M4.1 rule bool fCorePropertiesRelationship = false; ///xmlRelationshipsDoc.ChildNodes.GetEnumerator(); XPathNavigator xpathnav = xmlRelationshipsDoc.CreateNavigator(); XmlNamespaceManager nsMgr = new XmlNamespaceManager(xpathnav.NameTable); nsMgr.AddNamespace("x", PackageNamespaces.RELATIONSHIPS); XPathNodeIterator iterator = xpathnav.Select("//x:" + PackageRelationship.RELATIONSHIP_TAG_NAME, nsMgr); while (iterator.MoveNext()) { // Relationship ID String id = iterator.Current.GetAttribute(PackageRelationship.ID_ATTRIBUTE_NAME, xpathnav.NamespaceURI); // Relationship type String type = iterator.Current.GetAttribute( PackageRelationship.TYPE_ATTRIBUTE_NAME, xpathnav.NamespaceURI); /* Check OPC Compliance */ // Check Rule M4.1 if (type.Equals(PackageRelationshipTypes.CORE_PROPERTIES)) { if (!fCorePropertiesRelationship) { fCorePropertiesRelationship = true; } else { throw new InvalidFormatException( "OPC Compliance error [M4.1]: there is more than one core properties relationship in the package !"); } } /* End OPC Compliance */ // TargetMode (default value "Internal") string targetModeAttr = iterator.Current.GetAttribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME, xpathnav.NamespaceURI); TargetMode targetMode = TargetMode.Internal; if (targetModeAttr != string.Empty) { targetMode = targetModeAttr.ToLower() .Equals("internal") ? TargetMode.Internal : TargetMode.External; } // Target converted in URI Uri target = PackagingUriHelper.ToUri("http://invalid.uri"); // dummy url String value = iterator.Current.GetAttribute( PackageRelationship.TARGET_ATTRIBUTE_NAME, xpathnav.NamespaceURI);; try { // when parsing of the given uri fails, we can either // ignore this relationship, which leads to InvalidOperationException // later on, or use a dummy value and thus enable processing of the // package target = PackagingUriHelper.ToUri(value); } catch (UriFormatException e) { logger.Log(POILogger.ERROR, "Cannot convert " + value + " in a valid relationship URI-> dummy-URI used", e); } AddRelationship(target, targetMode, type, id); } } catch (Exception e) { logger.Log(POILogger.ERROR, e); throw new InvalidFormatException(e.Message); } }
/** * Iterate through the underlying PackagePart and create child POIXMLFactory instances * using the specified factory * * @param factory the factory object that Creates POIXMLFactory instances * @param context context map Containing already visited noted keyed by tarGetURI */ protected void Read(POIXMLFactory factory, Dictionary <PackagePart, POIXMLDocumentPart> context) { try { PackageRelationshipCollection rels = packagePart.Relationships; foreach (PackageRelationship rel in rels) { if (rel.TargetMode == TargetMode.Internal) { Uri uri = rel.TargetUri; PackagePart p; if (uri.OriginalString.IndexOf('#') >= 0) { /* * For internal references (e.g. '#Sheet1!A1') the namespace part is null */ p = null; } else { PackagePartName relName = PackagingUriHelper.CreatePartName(uri); p = packagePart.Package.GetPart(relName); if (p == null) { logger.Log(POILogger.ERROR, "Skipped invalid entry " + rel.TargetUri); continue; } } if (p == null || !context.ContainsKey(p)) { POIXMLDocumentPart childPart = factory.CreateDocumentPart(this, rel, p); childPart.parent = this; AddRelation(rel.Id, childPart); if (p != null) { context[p] = childPart; if (p.HasRelationships) { childPart.Read(factory, context); } } } else { AddRelation(rel.Id, context[p]); } } } } catch (Exception ex) { if ((null != ex.InnerException) && (null != ex.InnerException.InnerException)) { // this type of exception is thrown when the XML Serialization does not match the input. logger.Log(1, ex.InnerException.InnerException); } throw; } }
/// <summary> /// Reads the dictionary. /// </summary> /// <param name="src">The byte array containing the bytes making out the dictionary.</param> /// <param name="offset">At this offset within src the dictionary starts.</param> /// <param name="Length">The dictionary Contains at most this many bytes.</param> /// <param name="codepage">The codepage of the string values.</param> /// <returns>The dictonary</returns> protected IDictionary ReadDictionary(byte[] src, long offset, int Length, int codepage) { /* Check whether "offset" points into the "src" array". */ if (offset < 0 || offset > src.Length) { throw new HPSFRuntimeException ("Illegal offset " + offset + " while HPSF stream Contains " + Length + " bytes."); } int o = (int)offset; /* * Read the number of dictionary entries. */ long nrEntries = LittleEndian.GetUInt(src, o); o += LittleEndianConsts.INT_SIZE; Hashtable m = new Hashtable((int)nrEntries, (float)1.0); try { for (int i = 0; i < nrEntries; i++) { /* The key. */ long id = LittleEndian.GetUInt(src, o); o += LittleEndianConsts.INT_SIZE; /* The value (a string). The Length is the either the * number of (two-byte) characters if the character Set is Unicode * or the number of bytes if the character Set is not Unicode. * The Length includes terminating 0x00 bytes which we have To strip * off To Create a Java string. */ long sLength = LittleEndian.GetUInt(src, o); o += LittleEndianConsts.INT_SIZE; /* Read the string. */ StringBuilder b = new StringBuilder(); switch (codepage) { case -1: { /* Without a codepage the Length is equal To the number of * bytes. */ b.Append(Encoding.UTF8.GetString(src, o, (int)sLength)); break; } case (int)Constants.CP_UNICODE: { /* The Length is the number of characters, i.e. the number * of bytes is twice the number of the characters. */ int nrBytes = (int)(sLength * 2); byte[] h = new byte[nrBytes]; for (int i2 = 0; i2 < nrBytes; i2 += 2) { h[i2] = src[o + i2 + 1]; h[i2 + 1] = src[o + i2]; } b.Append(Encoding.GetEncoding(codepage).GetString(h, 0, nrBytes)); break; } default: { /* For encodings other than Unicode the Length is the number * of bytes. */ b.Append(Encoding.GetEncoding(codepage).GetString(src, o, (int)sLength)); break; } } /* Strip 0x00 characters from the end of the string: */ while (b.Length > 0 && b[b.Length - 1] == 0x00) { b.Length = b.Length - 1; } if (codepage == (int)Constants.CP_UNICODE) { if (sLength % 2 == 1) { sLength++; } o += (int)(sLength + sLength); } else { o += (int)sLength; } m[id] = b.ToString(); } } catch (Exception ex) { POILogger l = POILogFactory.GetLogger(typeof(Property)); l.Log(POILogger.WARN, "The property Set's dictionary Contains bogus data. " + "All dictionary entries starting with the one with ID " + id + " will be ignored.", ex); } return(m); }
public void Rebuild(ComplexFileTable complexFileTable) { long start = DateTime.Now.Ticks; if (complexFileTable != null) { SprmBuffer[] sprmBuffers = complexFileTable.GetGrpprls(); // adding CHPX from fast-saved SPRMs foreach (TextPiece textPiece in complexFileTable.GetTextPieceTable() .TextPieces) { PropertyModifier prm = textPiece.PieceDescriptor.Prm; if (!prm.IsComplex()) { continue; } int igrpprl = prm.GetIgrpprl(); if (igrpprl < 0 || igrpprl >= sprmBuffers.Length) { logger.Log(POILogger.WARN, textPiece + "'s PRM references to unknown grpprl"); continue; } bool hasChp = false; SprmBuffer sprmBuffer = sprmBuffers[igrpprl]; for (SprmIterator iterator = sprmBuffer.Iterator(); ; iterator .HasNext()) { SprmOperation sprmOperation = iterator.Next(); if (sprmOperation.Type == SprmOperation.TYPE_CHP) { hasChp = true; break; } } if (hasChp) { SprmBuffer newSprmBuffer; newSprmBuffer = (SprmBuffer)sprmBuffer.Clone(); CHPX chpx = new CHPX(textPiece.Start, textPiece.End, newSprmBuffer); _textRuns.Add(chpx); } } logger.Log(POILogger.DEBUG, "Merged with CHPX from complex file table in ", DateTime.Now.Ticks - start, " ms (", _textRuns.Count, " elements in total)"); start = DateTime.Now.Ticks; } List <CHPX> oldChpxSortedByStartPos = new List <CHPX>(_textRuns); oldChpxSortedByStartPos.Sort( (IComparer <CHPX>)PropertyNode.CHPXComparator.instance); logger.Log(POILogger.DEBUG, "CHPX sorted by start position in ", DateTime.Now.Ticks - start, " ms"); start = DateTime.Now.Ticks; Dictionary <CHPX, int> chpxToFileOrder = new Dictionary <CHPX, int>(); int counter = 0; foreach (CHPX chpx in _textRuns) { chpxToFileOrder.Add(chpx, counter++); } logger.Log(POILogger.DEBUG, "CHPX's order map created in ", DateTime.Now.Ticks - start, " ms"); start = DateTime.Now.Ticks; List <int> textRunsBoundariesList; List <int> textRunsBoundariesSet = new List <int>(); foreach (CHPX chpx in _textRuns) { textRunsBoundariesSet.Add(chpx.Start); textRunsBoundariesSet.Add(chpx.End); } textRunsBoundariesSet.Remove(0); textRunsBoundariesList = new List <int>( textRunsBoundariesSet); textRunsBoundariesList.Sort(); logger.Log(POILogger.DEBUG, "Texts CHPX boundaries collected in ", DateTime.Now.Ticks - start, " ms"); start = DateTime.Now.Ticks; List <CHPX> newChpxs = new List <CHPX>(); int lastTextRunStart = 0; foreach (int objBoundary in textRunsBoundariesList) { int boundary = objBoundary; int startInclusive = lastTextRunStart; int endExclusive = boundary; lastTextRunStart = endExclusive; int startPosition = BinarySearch(oldChpxSortedByStartPos, boundary); startPosition = Math.Abs(startPosition); while (startPosition >= oldChpxSortedByStartPos.Count) { startPosition--; } while (startPosition > 0 && oldChpxSortedByStartPos[startPosition].Start >= boundary) { startPosition--; } List <CHPX> chpxs = new List <CHPX>(); for (int c = startPosition; c < oldChpxSortedByStartPos.Count; c++) { CHPX chpx = oldChpxSortedByStartPos[c]; if (boundary < chpx.Start) { break; } int left = Math.Max(startInclusive, chpx.Start); int right = Math.Min(endExclusive, chpx.End); if (left < right) { chpxs.Add(chpx); } } if (chpxs.Count == 0) { logger.Log(POILogger.WARN, "Text piece [", startInclusive, "; ", endExclusive, ") has no CHPX. Creating new one."); // create it manually CHPX chpx = new CHPX(startInclusive, endExclusive, new SprmBuffer(0)); newChpxs.Add(chpx); continue; } if (chpxs.Count == 1) { // can we reuse existing? CHPX existing = chpxs[0]; if (existing.Start == startInclusive && existing.End == endExclusive) { newChpxs.Add(existing); continue; } } CHPXToFileComparer chpxFileOrderComparator = new CHPXToFileComparer(chpxToFileOrder); chpxs.Sort(chpxFileOrderComparator); SprmBuffer sprmBuffer = new SprmBuffer(0); foreach (CHPX chpx in chpxs) { sprmBuffer.Append(chpx.GetGrpprl(), 0); } CHPX newChpx = new CHPX(startInclusive, endExclusive, sprmBuffer); newChpxs.Add(newChpx); continue; } this._textRuns = new List <CHPX>(newChpxs); logger.Log(POILogger.DEBUG, "CHPX rebuilded in ", DateTime.Now.Ticks - start, " ms (", _textRuns.Count, " elements)"); start = DateTime.Now.Ticks; CHPX previous = null; for (int iterator = _textRuns.Count; iterator != 0;) { CHPX current = previous; previous = _textRuns[--iterator]; if (current == null) { continue; } if (previous.End == current.Start && Arrays .Equals(previous.GetGrpprl(), current.GetGrpprl())) { previous.End = current.End; _textRuns.Remove(current); continue; } previous = current; } logger.Log(POILogger.DEBUG, "CHPX compacted in ", DateTime.Now.Ticks - start, " ms (", _textRuns.Count, " elements)"); }
/** * Constructs an EmbeddedObjectRef record and Sets its fields appropriately. * * @param in the record input stream. */ public EmbeddedObjectRefSubRecord(ILittleEndianInput in1, int size) { // Much guess-work going on here due to lack of any documentation. // See similar source code in OOO: // http://lxr.go-oo.org/source/sc/sc/source/filter/excel/xiescher.cxx // 1223 void XclImpOleObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nRecSize ) int streamIdOffset = in1.ReadShort(); // OOO calls this 'nFmlaLen' int remaining = size - LittleEndianConsts.SHORT_SIZE; int dataLenAfterFormula = remaining - streamIdOffset; int formulaSize = in1.ReadUShort(); remaining -= LittleEndianConsts.SHORT_SIZE; field_1_unknown_int = in1.ReadInt(); remaining -= LittleEndianConsts.INT_SIZE; byte[] formulaRawBytes = ReadRawData(in1, formulaSize); remaining -= formulaSize; field_2_refPtg = ReadRefPtg(formulaRawBytes); if (field_2_refPtg == null) { // common case // field_2_n16 seems to be 5 here // The formula almost looks like tTbl but the row/column values seem like garbage. field_2_unknownFormulaData = formulaRawBytes; } else { field_2_unknownFormulaData = null; } int stringByteCount; if (remaining >= dataLenAfterFormula + 3) { int tag = in1.ReadByte(); stringByteCount = LittleEndianConsts.BYTE_SIZE; if (tag != 0x03) { throw new RecordFormatException("Expected byte 0x03 here"); } int nChars = in1.ReadUShort(); stringByteCount += LittleEndianConsts.SHORT_SIZE; if (nChars > 0) { // OOO: the 4th way Xcl stores a unicode string: not even a Grbit byte present if Length 0 field_3_unicode_flag = (in1.ReadByte() & 0x01) != 0; stringByteCount += LittleEndianConsts.BYTE_SIZE; if (field_3_unicode_flag) { field_4_ole_classname = StringUtil.ReadUnicodeLE(in1, nChars); stringByteCount += nChars * 2; } else { field_4_ole_classname = StringUtil.ReadCompressedUnicode(in1, nChars); stringByteCount += nChars; } } else { field_4_ole_classname = ""; } } else { field_4_ole_classname = null; stringByteCount = 0; } remaining -= stringByteCount; // Pad to next 2-byte boundary if (((stringByteCount + formulaSize) % 2) != 0) { int b = in1.ReadByte(); remaining -= LittleEndianConsts.BYTE_SIZE; if (field_2_refPtg != null && field_4_ole_classname == null) { field_4_unknownByte = (byte)b; } } int nUnexpectedPadding = remaining - dataLenAfterFormula; if (nUnexpectedPadding > 0) { logger.Log(POILogger.ERROR, "Discarding " + nUnexpectedPadding + " unexpected padding bytes "); ReadRawData(in1, nUnexpectedPadding); remaining -= nUnexpectedPadding; } // Fetch the stream ID if (dataLenAfterFormula >= 4) { field_5_stream_id = in1.ReadInt(); remaining -= LittleEndianConsts.INT_SIZE; } else { field_5_stream_id = null; } field_6_unknown = ReadRawData(in1, remaining); }
protected override void ProcessTable(HWPFDocumentCore wordDocument, XmlElement flow, Table table) { XmlElement tableHeader = htmlDocumentFacade.CreateTableHeader(); XmlElement tableBody = htmlDocumentFacade.CreateTableBody(); int[] tableCellEdges = WordToHtmlUtils.BuildTableCellEdgesArray(table); int tableRows = table.NumRows; int maxColumns = int.MinValue; for (int r = 0; r < tableRows; r++) { maxColumns = Math.Max(maxColumns, table.GetRow(r).NumCells()); } for (int r = 0; r < tableRows; r++) { TableRow tableRow = table.GetRow(r); XmlElement tableRowElement = htmlDocumentFacade.CreateTableRow(); StringBuilder tableRowStyle = new StringBuilder(); WordToHtmlUtils.AddTableRowProperties(tableRow, tableRowStyle); // index of current element in tableCellEdges[] int currentEdgeIndex = 0; int rowCells = tableRow.NumCells(); for (int c = 0; c < rowCells; c++) { TableCell tableCell = tableRow.GetCell(c); if (tableCell.IsVerticallyMerged() && !tableCell.IsFirstVerticallyMerged()) { currentEdgeIndex += getTableCellEdgesIndexSkipCount(table, r, tableCellEdges, currentEdgeIndex, c, tableCell); continue; } XmlElement tableCellElement; if (tableRow.isTableHeader()) { tableCellElement = htmlDocumentFacade.CreateTableHeaderCell(); } else { tableCellElement = htmlDocumentFacade.CreateTableCell(); } StringBuilder tableCellStyle = new StringBuilder(); WordToHtmlUtils.AddTableCellProperties(tableRow, tableCell, r == 0, r == tableRows - 1, c == 0, c == rowCells - 1, tableCellStyle); int colSpan = GetNumberColumnsSpanned(tableCellEdges, currentEdgeIndex, tableCell); currentEdgeIndex += colSpan; if (colSpan == 0) { continue; } if (colSpan != 1) { tableCellElement.SetAttribute("colspan", colSpan.ToString()); } int rowSpan = GetNumberRowsSpanned(table, r, c, tableCell); if (rowSpan > 1) { tableCellElement.SetAttribute("rowspan", rowSpan.ToString()); } ProcessParagraphes(wordDocument, tableCellElement, tableCell, 0 /*table.TableLevel Todo: */); if (!tableCellElement.HasChildNodes) { tableCellElement.AppendChild(htmlDocumentFacade.CreateParagraph()); } if (tableCellStyle.Length > 0) { htmlDocumentFacade.AddStyleClass(tableCellElement, tableCellElement.LocalName, tableCellStyle.ToString()); } tableRowElement.AppendChild(tableCellElement); } if (tableRowStyle.Length > 0) { tableRowElement.SetAttribute("class", htmlDocumentFacade.GetOrCreateCssClass("tr", "r", tableRowStyle.ToString())); } if (tableRow.isTableHeader()) { tableHeader.AppendChild(tableRowElement); } else { tableBody.AppendChild(tableRowElement); } } XmlElement tableElement = htmlDocumentFacade.CreateTable(); tableElement.SetAttribute("class", htmlDocumentFacade.GetOrCreateCssClass(tableElement.LocalName, "t", "table-layout:fixed;border-collapse:collapse;border-spacing:0;")); if (tableHeader.HasChildNodes) { tableElement.AppendChild(tableHeader); } if (tableBody.HasChildNodes) { tableElement.AppendChild(tableBody); flow.AppendChild(tableElement); } else { logger.Log(POILogger.WARN, "Table without body starting at [", table.StartOffset.ToString(), "; ", table.EndOffset.ToString(), ")"); } }
private static void Log(String msg) { log.Log(POILogger.INFO, msg); }
/** * Save this package into the specified stream * * * @param outputStream * The stream use to save this package. * * @see #save(OutputStream) */ protected override void SaveImpl(Stream outputStream) { // Check that the document was open in write mode ThrowExceptionIfReadOnly(); ZipOutputStream zos = null; try { if (!(outputStream is ZipOutputStream)) { zos = new ZipOutputStream(outputStream); } else { zos = (ZipOutputStream)outputStream; } zos.UseZip64 = UseZip64.Off; // If the core properties part does not exist in the part list, // we save it as well if (this.GetPartsByRelationshipType(PackageRelationshipTypes.CORE_PROPERTIES).Count == 0 && this.GetPartsByRelationshipType(PackageRelationshipTypes.CORE_PROPERTIES_ECMA376).Count == 0) { logger.Log(POILogger.DEBUG, "Save core properties part"); // Ensure that core properties are added if missing GetPackageProperties(); // Add core properties to part list ... AddPackagePart(this.packageProperties); // ... and to add its relationship ... this.relationships.AddRelationship(this.packageProperties .PartName.URI, TargetMode.Internal, PackageRelationshipTypes.CORE_PROPERTIES, null); // ... and the content if it has not been added yet. if (!this.contentTypeManager .IsContentTypeRegister(ContentTypes.CORE_PROPERTIES_PART)) { this.contentTypeManager.AddContentType( this.packageProperties.PartName, ContentTypes.CORE_PROPERTIES_PART); } } // Save package relationships part. logger.Log(POILogger.DEBUG, "Save package relationships"); ZipPartMarshaller.MarshallRelationshipPart(this.Relationships, PackagingUriHelper.PACKAGE_RELATIONSHIPS_ROOT_PART_NAME, zos); // Save content type part. logger.Log(POILogger.DEBUG, "Save content types part"); this.contentTypeManager.Save(zos); // Save parts. foreach (PackagePart part in GetParts()) { // If the part is a relationship part, we don't save it, it's // the source part that will do the job. if (part.IsRelationshipPart) { continue; } logger.Log(POILogger.DEBUG, "Save part '" + ZipHelper.GetZipItemNameFromOPCName(part .PartName.Name) + "'"); if (partMarshallers.ContainsKey(part._contentType)) { PartMarshaller marshaller = partMarshallers[part._contentType]; if (!marshaller.Marshall(part, zos)) { throw new OpenXml4NetException( "The part " + part.PartName.URI + " fail to be saved in the stream with marshaller " + marshaller); } } else { if (!defaultPartMarshaller.Marshall(part, zos)) { throw new OpenXml4NetException( "The part " + part.PartName.URI + " fail to be saved in the stream with marshaller " + defaultPartMarshaller); } } } //Finishes writing the contents of the ZIP output stream without closing the underlying stream. if (isStream) { zos.Finish(); //instead of use zos.Close, it will close the stream } else { zos.Close(); } } catch (Exception e) { logger.Log(POILogger.ERROR, "fail to save: an error occurs while saving the package : " + e.Message); } }
/** * Converts the Records into UserModel * objects on the bound HSSFPatriarch */ public void ConvertRecordsToUserModel() { if (patriarch == null) { throw new InvalidOperationException("Must call SetPatriarch() first"); } // The top level container ought to have // the DgRecord and the container of one container // per shape Group (patriach overall first) EscherContainerRecord topContainer = (EscherContainerRecord)GetEscherContainer(); if (topContainer == null) { return; } topContainer = (EscherContainerRecord) topContainer.ChildContainers[0]; IList <EscherContainerRecord> tcc = topContainer.ChildContainers; if (tcc.Count == 0) { throw new InvalidOperationException("No child escher containers at the point that should hold the patriach data, and one container per top level shape!"); } // First up, Get the patriach position // This Is in the first EscherSpgrRecord, in // the first container, with a EscherSRecord too EscherContainerRecord patriachContainer = (EscherContainerRecord)tcc[0]; EscherSpgrRecord spgr = null; for (IEnumerator it = patriachContainer.ChildRecords.GetEnumerator(); it.MoveNext();) { EscherRecord r = (EscherRecord)it.Current; if (r is EscherSpgrRecord) { spgr = (EscherSpgrRecord)r; break; } } if (spgr != null) { patriarch.SetCoordinates( spgr.RectX1, spgr.RectY1, spgr.RectX2, spgr.RectY2 ); } // Now Process the containers for each Group // and objects for (int i = 1; i < tcc.Count; i++) { EscherContainerRecord shapeContainer = (EscherContainerRecord)tcc[i]; //Console.Error.WriteLine("\n\n*****\n\n"); //Console.Error.WriteLine(shapeContainer); // Could be a Group, or a base object if (shapeContainer.RecordId == EscherContainerRecord.SPGR_CONTAINER) { if (shapeContainer.ChildRecords.Count > 0) { // Group HSSFShapeGroup group = new HSSFShapeGroup(null, new HSSFClientAnchor()); patriarch.Children.Add(group); EscherContainerRecord groupContainer = (EscherContainerRecord)shapeContainer.GetChild(0); ConvertRecordsToUserModel(groupContainer, group); } } else if (shapeContainer.RecordId == EscherContainerRecord.SP_CONTAINER) { EscherSpRecord spRecord = shapeContainer.GetChildById(EscherSpRecord.RECORD_ID); int type = spRecord.Options >> 4; switch (type) { case ST_TEXTBOX: // TextBox HSSFTextbox box = new HSSFTextbox(null, new HSSFClientAnchor()); patriarch.Children.Add(box); ConvertRecordsToUserModel(shapeContainer, box); break; case ST_PICTUREFRAME: // Duplicated from // org.apache.poi.hslf.model.Picture.getPictureIndex() EscherOptRecord opt = (EscherOptRecord)GetEscherChild(shapeContainer, EscherOptRecord.RECORD_ID); EscherSimpleProperty prop = (EscherSimpleProperty)opt.Lookup(EscherProperties.BLIP__BLIPTODISPLAY); if (prop != null) { int pictureIndex = prop.PropertyValue; EscherClientAnchorRecord anchorRecord = (EscherClientAnchorRecord)GetEscherChild(shapeContainer, EscherClientAnchorRecord.RECORD_ID); HSSFClientAnchor anchor = new HSSFClientAnchor(); anchor.Col1 = anchorRecord.Col1; anchor.Col2 = anchorRecord.Col2; anchor.Dx1 = anchorRecord.Dx1; anchor.Dx2 = anchorRecord.Dx2; anchor.Dy1 = anchorRecord.Dy1; anchor.Dy2 = anchorRecord.Dy2; anchor.Row1 = anchorRecord.Row1; anchor.Row2 = anchorRecord.Row2; HSSFPicture picture = new HSSFPicture(null, anchor); picture.PictureIndex = pictureIndex; patriarch.AddShape(picture); } break; } } else { // Base level ConvertRecordsToUserModel(shapeContainer, patriarch); } } // Now, clear any trace of what records make up // the patriarch // Otherwise, everything will go horribly wrong // when we try to Write out again.... // clearEscherRecords(); drawingManager.GetDgg().FileIdClusters = new EscherDggRecord.FileIdCluster[0]; // TODO: Support Converting our records // back into shapes log.Log(POILogger.WARN, "Not Processing objects into Patriarch!"); }