1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package org.openoffice.xmerge.converter.xml.sxc.pexcel; 25 26 import java.io.IOException; 27 import java.util.Vector; 28 29 import org.openoffice.xmerge.util.Debug; 30 31 import org.openoffice.xmerge.converter.xml.sxc.SpreadsheetEncoder; 32 import org.openoffice.xmerge.converter.xml.sxc.Format; 33 import org.openoffice.xmerge.converter.xml.sxc.BookSettings; 34 import org.openoffice.xmerge.converter.xml.sxc.NameDefinition; 35 import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.Workbook; 36 37 /** 38 * This class is used by {@link SxcDocumentSerializerImpl} to encode the Pocket Excel format. 39 * 40 * @author Martin Maher 41 */ 42 final class PocketExcelEncoder extends SpreadsheetEncoder { 43 44 private Workbook wb; 45 46 /** 47 * Constructor creates a Pocket Excel WorkBook. 48 * 49 * @param name The name of the WorkBook. 50 * @param password The password for the WorkBook. 51 * 52 * @throws IOException If any I/O error occurs. 53 */ PocketExcelEncoder(String name, String password)54 PocketExcelEncoder(String name, String password) throws IOException { 55 56 super(name, password); 57 wb = new Workbook(name); 58 59 } 60 61 62 /** 63 * This method creates a WorkSheet belonging to the 64 * WorkBook. 65 * 66 * @param sheetName The name of the WorkSheet. 67 * 68 * @throws IOException If any I/O error occurs. 69 */ createWorksheet(String sheetName)70 public void createWorksheet(String sheetName) throws IOException { 71 72 wb.addWorksheet(sheetName); 73 } 74 75 76 /** 77 * This method gets the number of sheets in the WorkBook. 78 * 79 * @return The number of sheets in the WorkBook. 80 */ getNumberOfSheets()81 public int getNumberOfSheets() { 82 83 Vector v = wb.getWorksheetNames(); 84 return (v.size()); 85 } 86 87 88 /** 89 * This method returns the Workbook created. 90 * 91 * @return Returns a <code>Workbook</code> 92 * 93 * @throws IOException If any I/O error occurs. 94 */ getWorkbook()95 public Workbook getWorkbook() throws IOException { 96 97 return wb; 98 } 99 100 /** 101 * This method converts a String containing a formula in infix notation 102 * to a String in Reverse Polish Notation (RPN) 103 * 104 * @return a parsed pexcel formula in RPN 105 */ parseFormula(String formula)106 protected String parseFormula(String formula) { 107 108 Debug.log(Debug.TRACE,"Strip Formula (Before) : " + formula); 109 110 StringBuffer inFormula = new StringBuffer(formula); 111 StringBuffer outFormula = new StringBuffer(); 112 113 boolean inBrace = false; 114 boolean firstCharAfterBrace = false; 115 boolean firstCharAfterColon = false; 116 117 int len = inFormula.length(); 118 119 for (int in = 0; in < len; in++) { 120 switch (inFormula.charAt(in)) { 121 case '[': 122 // We are now inside a StarOffice cell reference. 123 // We also need to strip out the '[' 124 Debug.log(Debug.TRACE,"brace Found"); 125 inBrace = true; 126 127 // If the next character is a '.', we want to strip it out 128 firstCharAfterBrace = true; 129 break; 130 131 case ']': 132 // We are exiting a StarOffice cell reference 133 // We are stripping out the ']' 134 inBrace = false; 135 break; 136 case '.': 137 if (inBrace == true && (firstCharAfterBrace == true || 138 firstCharAfterColon == true) ) { 139 140 Debug.log(Debug.TRACE,"dot Found and in brace"); 141 // Since we are in a StarOffice cell reference, 142 // and we are the first character, we need to 143 // strip out the '.' 144 firstCharAfterBrace = false; 145 firstCharAfterColon = false; 146 147 } else if(firstCharAfterColon == true) { 148 firstCharAfterColon = false; 149 } else { 150 outFormula.append(inFormula.charAt(in)); 151 } 152 break; 153 154 case ':': 155 // We have a cell range reference. 156 // May need to strip out the leading '.' 157 firstCharAfterColon = true; 158 outFormula.append(inFormula.charAt(in)); 159 break; 160 161 case ';': 162 // StarOffice XML format uses ';' as a separator. MiniCalc (and 163 // many spreadsheets) use ',' as a separator instead. 164 outFormula.append(','); 165 break; 166 167 default: 168 // We hit valid data, lets add it to the formula string 169 outFormula.append(inFormula.charAt(in)); 170 171 // Need to make sure that firstCharAfterBrace is not true. 172 firstCharAfterBrace = false; 173 break; 174 } 175 } 176 177 Debug.log(Debug.TRACE,"Strip Formula (After) : " + outFormula); 178 return outFormula.toString(); 179 } 180 181 /** 182 * Add a cell to the current WorkSheet. 183 * 184 * @param row The row number of the cell. 185 * @param column The column number of the cell. 186 * @param fmt The <code>Format</code> object describing 187 * the appearance of this cell. 188 * @param cellContents The text or formula of the cell's contents. 189 * 190 * @throws IOException If any I/O error occurs. 191 */ addCell(int row, int column, Format fmt, String cellContents)192 public void addCell(int row, int column, Format fmt, String cellContents) throws IOException { 193 194 if (cellContents.startsWith("=")) { 195 cellContents = parseFormula(cellContents); 196 Debug.log(Debug.TRACE,"Parsing Formula " + cellContents); 197 } 198 wb.addCell(row, column, fmt, cellContents); 199 } 200 201 202 /** 203 * Set the width of the columns in the WorkBook. 204 * 205 * @param columnWidths An <code>IntArrayList</code> of column 206 * widths. 207 */ setColumnRows(Vector columnRows)208 public void setColumnRows(Vector columnRows) throws IOException { 209 210 wb.addColInfo(columnRows); 211 } 212 213 /** 214 * Set the width of the columns in the WorkBook. 215 * 216 * @param columnWidths An <code>IntArrayList</code> of column 217 * widths. 218 */ setNameDefinition(NameDefinition nd)219 public void setNameDefinition(NameDefinition nd) throws IOException { 220 221 String parsedName = nd.getDefinition(); 222 nd.setDefinition(parseFormula(parsedName)); 223 224 wb.addNameDefinition(nd); 225 } 226 227 /** 228 * Set the width of the columns in the WorkBook. 229 * 230 * @param columnWidths An <code>IntArrayList</code> of column 231 * widths. 232 */ addSettings(BookSettings s)233 public void addSettings(BookSettings s) throws IOException { 234 235 wb.addSettings(s); 236 } 237 238 /** 239 * This method sets the format of a cell to <i>string</i>. 240 * 241 * @param format The cell format-may already contain display info, 242 * such as alignment or font type. 243 * 244 * @return The updated format of the cell. 245 */ setFormatString(long format)246 private long setFormatString(long format) { 247 248 return 0; 249 } 250 251 252 /** 253 * Set a cell's formatting options via a separately create 254 * <code>Format</code> object. 255 * 256 * @param row The row number of the cell to be changed. 257 * @param column The column number of the cell to be changed. 258 * @param fmt Object containing formatting settings for 259 * this cell. 260 */ setCellFormat(int row, int column, Format fmt)261 public void setCellFormat(int row, int column, Format fmt) { 262 Debug.log(Debug.TRACE,"bold : " + fmt.getAttribute(Format.BOLD) + 263 ",Italic : " + fmt.getAttribute(Format.ITALIC) + 264 ",Underline : " + fmt.getAttribute(Format.UNDERLINE)); 265 } 266 267 268 /** 269 * Get the names of the sheets in the WorkBook. 270 * 271 * @param sheet The required sheet. 272 */ getSheetName(int sheet)273 public String getSheetName(int sheet) { 274 275 Vector v = wb.getWorksheetNames(); 276 String wsName = (String) (v.elementAt(sheet)); 277 278 return wsName; 279 } 280 281 282 } 283 284