/** * This method process the cells in a <code>Document</code> and generates a portion of the <code> * Document</code>. * * <p>This method assumes that records are sorted by row and then column. * * @param root The <code>Node</code> of the <code>Document</code> we are building that we will * append our cell <code>Node</code> objects. This <code>Node</code> should be a TAG_TABLE * tag. * @throws IOException If any I/O error occurs. */ protected void processColumns(Node root) throws IOException { for (Iterator<ColumnRowInfo> e = decoder.getColumnRowInfos(); e.hasNext(); ) { ColumnRowInfo ci = e.next(); if (ci.isColumn()) { ColumnStyle cStyle = new ColumnStyle( "Default", SxcConstants.COLUMN_STYLE_FAMILY, SxcConstants.DEFAULT_STYLE, ci.getSize(), null); Style result[] = styleCat.getMatching(cStyle); String styleName; if (result.length == 0) { cStyle.setName("co" + colStyles++); styleName = cStyle.getName(); Debug.log(Debug.TRACE, "No existing style found, adding " + styleName); styleCat.add(cStyle); } else { ColumnStyle existingStyle = (ColumnStyle) result[0]; styleName = existingStyle.getName(); Debug.log(Debug.TRACE, "Existing style found : " + styleName); } // Create an element node for the new row Element colElement = doc.createElement(TAG_TABLE_COLUMN); colElement.setAttribute(ATTRIBUTE_TABLE_STYLE_NAME, styleName); if (ci.getRepeated() != 1) { String repeatStr = String.valueOf(ci.getRepeated()); colElement.setAttribute(ATTRIBUTE_TABLE_NUM_COLUMNS_REPEATED, repeatStr); } root.appendChild(colElement); } } }
/** * This method process the cells in a <code>Document</code> and generates a portion of the <code> * Document</code>. * * <p>This method assumes that records are sorted by row and then column. * * @param root The <code>Node</code> of the <code>Document</code> we are building that we will * append our cell <code>Node</code> objects. This <code>Node</code> should be a TAG_TABLE * tag. * @throws IOException If any I/O error occurs. */ protected void processCells(Node root) throws IOException { // The current row element Element rowElement = null; // The current cell element Element cellElement = null; // The row number - we may not have any rows (empty sheet) // so set to zero. int row = 0; // The column number - This is the expected column number of // the next cell we are reading. int col = 1; // The number of columns in the spreadsheet int lastColumn = decoder.getNumberOfColumns(); Node autoStylesNode = null; // Loop over all cells in the spreadsheet while (decoder.goToNextCell()) { // Get the row number int newRow = decoder.getRowNumber(); // Is the cell in a new row, or part of the current row? if (newRow != row) { // Make sure that all the cells in the previous row // have been entered. if (col <= lastColumn && rowElement != null) { int numSkippedCells = lastColumn - col + 1; addEmptyCells(numSkippedCells, rowElement); } // log an end row - if we already have a row if (row != 0) { Debug.log(Debug.TRACE, "</tr>"); } // How far is the new row from the last row? int deltaRows = newRow - row; // Check if we have skipped any rows if (deltaRows > 1) { // Add in empty rows addEmptyRows(deltaRows - 1, root, lastColumn); } // Re-initialize column (since we are in a new row) col = 1; // Create an element node for the new row rowElement = doc.createElement(TAG_TABLE_ROW); for (Iterator<ColumnRowInfo> e = decoder.getColumnRowInfos(); e.hasNext(); ) { ColumnRowInfo cri = e.next(); if (cri.isRow() && cri.getRepeated() == newRow - 1) { // We have the correct Row BIFFRecord for this row RowStyle rStyle = new RowStyle( "Default", SxcConstants.ROW_STYLE_FAMILY, SxcConstants.DEFAULT_STYLE, cri.getSize(), null); Style result[] = styleCat.getMatching(rStyle); String styleName; if (result.length == 0) { rStyle.setName("ro" + rowStyles++); styleName = rStyle.getName(); Debug.log(Debug.TRACE, "No existing style found, adding " + styleName); styleCat.add(rStyle); } else { RowStyle existingStyle = (RowStyle) result[0]; styleName = existingStyle.getName(); Debug.log(Debug.TRACE, "Existing style found : " + styleName); } rowElement.setAttribute(ATTRIBUTE_TABLE_STYLE_NAME, styleName); // For now we will not use the repeat column attribute } } // Append the row element to the root node root.appendChild(rowElement); // Update row number row = newRow; Debug.log(Debug.TRACE, "<tr>"); } // Get the column number of the current cell int newCol = decoder.getColNumber(); // Check to see if some columns were skipped if (newCol != col) { // How many columns have we skipped? int numColsSkipped = newCol - col; addEmptyCells(numColsSkipped, rowElement); // Update the column number to account for the // skipped cells col = newCol; } // Lets start dealing with the cell data Debug.log(Debug.TRACE, "<td>"); // Get the cell's contents String cellContents = decoder.getCellContents(); // Get the type of the data in the cell String cellType = decoder.getCellDataType(); // Get the cell format Format fmt = decoder.getCellFormat(); // Create an element node for the cell cellElement = doc.createElement(TAG_TABLE_CELL); Node bodyNode = doc.getElementsByTagName(TAG_OFFICE_BODY).item(0); // Not every document has an automatic style tag autoStylesNode = doc.getElementsByTagName(TAG_OFFICE_AUTOMATIC_STYLES).item(0); if (autoStylesNode == null) { autoStylesNode = doc.createElement(TAG_OFFICE_AUTOMATIC_STYLES); doc.insertBefore(autoStylesNode, bodyNode); } CellStyle tStyle = new CellStyle( "Default", SxcConstants.TABLE_CELL_STYLE_FAMILY, SxcConstants.DEFAULT_STYLE, fmt, null); String styleName; Style result[] = styleCat.getMatching(tStyle); if (result.length == 0) { tStyle.setName("ce" + textStyles++); styleName = tStyle.getName(); Debug.log(Debug.TRACE, "No existing style found, adding " + styleName); styleCat.add(tStyle); } else { CellStyle existingStyle = (CellStyle) result[0]; styleName = existingStyle.getName(); Debug.log(Debug.TRACE, "Existing style found : " + styleName); } cellElement.setAttribute(ATTRIBUTE_TABLE_STYLE_NAME, styleName); // Store the cell data into the appropriate attributes processCellData(cellElement, cellType, cellContents); // Append the cell element to the row node rowElement.appendChild(cellElement); // Append the cellContents as a text node Element textElement = doc.createElement(TAG_PARAGRAPH); cellElement.appendChild(textElement); textElement.appendChild(doc.createTextNode(cellContents)); Debug.log(Debug.TRACE, cellContents); Debug.log(Debug.TRACE, "</td>"); // Increment to the column number of the next expected cell col++; } // Make sure that the last row is padded correctly if (col <= lastColumn && rowElement != null) { int numSkippedCells = lastColumn - col + 1; addEmptyCells(numSkippedCells, rowElement); } // Now write the style catalog to the document if (autoStylesNode != null) { Debug.log(Debug.TRACE, "Well the autostyle node was found!!!"); NodeList nl = styleCat.writeNode(doc, "dummy").getChildNodes(); int nlLen = nl.getLength(); // nl.item reduces the length for (int i = 0; i < nlLen; i++) { autoStylesNode.appendChild(nl.item(0)); } } if (row != 0) { // The sheet does have rows, so write out a /tr Debug.log(Debug.TRACE, "</tr>"); } }
/** * This method traverses a <i>table:table-cell</i> element {@code Node}. * * @param node a <i>table:table-cell</i> {@code Node}. * @throws IOException if any I/O error occurs. */ protected void traverseCell(Node node) throws IOException { NamedNodeMap cellAtt = node.getAttributes(); fmt.clearFormatting(); // Get the type of data in the cell Node tableValueTypeNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_VALUE_TYPE); // Get the number of columns this cell is repeated Node colsRepeatedNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_NUM_COLUMNS_REPEATED); // Get the style type Node tableStyleNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_STYLE_NAME); String styleName = ""; if (tableStyleNode != null) { styleName = tableStyleNode.getNodeValue(); } CellStyle cStyle = null; if (styleName.equalsIgnoreCase("Default")) { Debug.log(Debug.TRACE, "No defined Style Attribute was found"); } else if (styleName.length() != 0) { cStyle = (CellStyle) styleCat.lookup( styleName, SxcConstants.TABLE_CELL_STYLE_FAMILY, null, CellStyle.class); } if (cStyle != null) { Format definedFormat = cStyle.getFormat(); fmt = new Format(definedFormat); } // There is a number of cols repeated attribute if (colsRepeatedNode != null) { // Get the number of times the cell is repeated String colsRepeatedString = colsRepeatedNode.getNodeValue(); colsRepeated = Integer.parseInt(colsRepeatedString); } else { // The cell is not repeated colsRepeated = 1; } // if there is no style we need to check to see if there is a default // cell style defined in the table-column's if (fmt.isDefault() && styleName.length() == 0) { int index = 1; for (Iterator<ColumnRowInfo> e = ColumnRowList.iterator(); e.hasNext(); ) { ColumnRowInfo cri = e.next(); if (cri.isColumn()) { if (colID >= index && colID < (index + cri.getRepeated())) { fmt = new Format(cri.getFormat()); } index += cri.getRepeated(); } } } if (tableValueTypeNode != null) { String cellType = tableValueTypeNode.getNodeValue(); if (cellType.equalsIgnoreCase(CELLTYPE_STRING)) { // has text:p tag fmt.setCategory(CELLTYPE_STRING); Node tableStringValueNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_STRING_VALUE); Debug.log(Debug.TRACE, "Cell Type String : " + tableStringValueNode); if (tableStringValueNode != null) { fmt.setValue(tableStringValueNode.getNodeValue()); } } else if (cellType.equalsIgnoreCase(CELLTYPE_FLOAT)) { // has table:value attribute // has text:p tag // Determine the number of decimal places StarCalc // is displaying for this floating point output. fmt.setCategory(CELLTYPE_FLOAT); fmt.setDecimalPlaces(getDecimalPlaces(node)); Node tableValueNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_VALUE); fmt.setValue(tableValueNode.getNodeValue()); } else if (cellType.equalsIgnoreCase(CELLTYPE_TIME)) { // has table:time-value attribute // has text:p tag - which is the value we convert fmt.setCategory(CELLTYPE_TIME); Node tableTimeNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_TIME_VALUE); fmt.setValue(tableTimeNode.getNodeValue()); } else if (cellType.equalsIgnoreCase(CELLTYPE_DATE)) { // has table:date-value attribute // has text:p tag - which is the value we convert fmt.setCategory(CELLTYPE_DATE); Node tableDateNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_DATE_VALUE); fmt.setValue(tableDateNode.getNodeValue()); } else if (cellType.equalsIgnoreCase(CELLTYPE_CURRENCY)) { // has table:currency // has table:value attribute // has text:p tag fmt.setCategory(CELLTYPE_CURRENCY); fmt.setDecimalPlaces(getDecimalPlaces(node)); Node tableValueNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_VALUE); fmt.setValue(tableValueNode.getNodeValue()); } else if (cellType.equalsIgnoreCase(CELLTYPE_BOOLEAN)) { // has table:boolean-value attribute // has text:p tag - which is the value we convert fmt.setCategory(CELLTYPE_BOOLEAN); Node tableBooleanNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_BOOLEAN_VALUE); fmt.setValue(tableBooleanNode.getNodeValue()); } else if (cellType.equalsIgnoreCase(CELLTYPE_PERCENT)) { // has table:value attribute // has text:p tag fmt.setCategory(CELLTYPE_PERCENT); fmt.setDecimalPlaces(getDecimalPlaces(node)); Node tableValueNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_VALUE); fmt.setValue(tableValueNode.getNodeValue()); } else { Debug.log(Debug.TRACE, "No defined value type" + cellType); // Should never get here } } Node tableFormulaNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_FORMULA); if (tableFormulaNode != null) { if (tableValueTypeNode == null) { // If there is no value-type Node we must assume string-value fmt.setCategory(CELLTYPE_STRING); Node tableStringValueNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_STRING_VALUE); fmt.setValue(tableStringValueNode.getNodeValue()); } String cellFormula = tableFormulaNode.getNodeValue(); addCell(cellFormula); } else { // Text node, Date node, or Time node Debug.log(Debug.INFO, "TextNode, DateNode, TimeNode or BooleanNode\n"); // This handles the case where we have style information but no content if (node.hasChildNodes()) { NodeList childList = node.getChildNodes(); int len = childList.getLength(); for (int i = 0; i < len; i++) { Node child = childList.item(i); if (child.getNodeType() == Node.ELEMENT_NODE) { String childName = child.getNodeName(); if (childName.equals(TAG_PARAGRAPH)) { traverseParagraph(child); } } } } else if (!fmt.isDefault()) { addCell(""); } } // Increase the column counter by the number of times the // last cell was repeated. colID += colsRepeated; // Re-initialize the number of columns repeated before processing // the next cell data. colsRepeated = 1; }
/** * This method traverses the <i>table:table-column</i> {@code Node}. * * <p>Not yet implemented. * * @param node A <i>table:table-column</i> {@code Node}. * @throws IOException If any I/O error occurs. */ protected void traverseTableColumn(Node node) throws IOException { Debug.log(Debug.TRACE, "traverseColumn() : "); NamedNodeMap cellAtt = node.getAttributes(); Node tableStyleNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_STYLE_NAME); Node tableNumColRepeatingNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_NUM_COLUMNS_REPEATED); Node tableDefaultCellStyle = cellAtt.getNamedItem(ATTRIBUTE_DEFAULT_CELL_STYLE); int repeatedColumns = 1; int columnWidth = 0; ColumnRowInfo col = new ColumnRowInfo(ColumnRowInfo.COLUMN); if (tableNumColRepeatingNode != null) { Debug.log( Debug.TRACE, "traverseColumn() repeated-cols : " + tableNumColRepeatingNode.getNodeValue()); repeatedColumns = Integer.parseInt(tableNumColRepeatingNode.getNodeValue()); col.setRepeated(repeatedColumns); } String cellStyleName = ""; if (tableDefaultCellStyle != null) { cellStyleName = tableDefaultCellStyle.getNodeValue(); Debug.log(Debug.TRACE, "traverseColumn() default-cell-style : " + cellStyleName); } CellStyle cellStyle = null; if (cellStyleName.equalsIgnoreCase("Default") || cellStyleName.length() == 0) { Debug.log(Debug.TRACE, "No default cell Style Attribute was found"); } else { cellStyle = (CellStyle) styleCat.lookup( cellStyleName, SxcConstants.TABLE_CELL_STYLE_FAMILY, null, CellStyle.class); } if (cellStyle != null) { Format defaultFmt = new Format(cellStyle.getFormat()); col.setFormat(defaultFmt); } String styleName = ""; if (tableStyleNode != null) { styleName = tableStyleNode.getNodeValue(); } if (styleName.equalsIgnoreCase("Default") || styleName.length() == 0) { Debug.log(Debug.TRACE, "No defined Style Attribute was found"); } else { ColumnStyle cStyle = (ColumnStyle) styleCat.lookup(styleName, SxcConstants.COLUMN_STYLE_FAMILY, null, ColumnStyle.class); columnWidth = cStyle != null ? cStyle.getColWidth() : 0; col.setSize(columnWidth); Debug.log(Debug.TRACE, "traverseColumn() Column Width : " + columnWidth); } ColumnRowList.add(col); }