| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==================================================================== */ |
| |
| package org.apache.poi.hssf.usermodel; |
| |
| import java.util.Arrays; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Vector; |
| |
| import org.apache.poi.hssf.model.InternalWorkbook; |
| import org.apache.poi.hssf.record.FormatRecord; |
| import org.apache.poi.ss.usermodel.BuiltinFormats; |
| import org.apache.poi.ss.usermodel.DataFormat; |
| |
| /** |
| * Identifies both built-in and user defined formats within a workbook.<p/> |
| * See {@link BuiltinFormats} for a list of supported built-in formats.<p/> |
| * |
| * <b>International Formats</b><br/> |
| * Since version 2003 Excel has supported international formats. These are denoted |
| * with a prefix "[$-xxx]" (where xxx is a 1-7 digit hexadecimal number). |
| * See the Microsoft article |
| * <a href="http://office.microsoft.com/assistance/hfws.aspx?AssetID=HA010346351033&CTT=6&Origin=EC010272491033"> |
| * Creating international number formats |
| * </a> for more details on these codes. |
| */ |
| public final class HSSFDataFormat implements DataFormat { |
| private static final String[] _builtinFormats = BuiltinFormats.getAll(); |
| |
| private final Vector<String> _formats = new Vector<String>(); |
| private final InternalWorkbook _workbook; |
| private boolean _movedBuiltins = false; // Flag to see if need to |
| // check the built in list |
| // or if the regular list |
| // has all entries. |
| |
| /** |
| * Constructs a new data formatter. It takes a workbook to have |
| * access to the workbooks format records. |
| * @param workbook the workbook the formats are tied to. |
| */ |
| HSSFDataFormat(InternalWorkbook workbook) { |
| _workbook = workbook; |
| |
| Iterator<FormatRecord> i = workbook.getFormats().iterator(); |
| while (i.hasNext()) { |
| FormatRecord r = i.next(); |
| ensureFormatsSize(r.getIndexCode()); |
| _formats.set(r.getIndexCode(), r.getFormatString()); |
| } |
| } |
| |
| public static List<String> getBuiltinFormats() { |
| return Arrays.asList(_builtinFormats); |
| } |
| |
| /** |
| * get the format index that matches the given format string<p> |
| * Automatically converts "text" to excel's format string to represent text. |
| * @param format string matching a built in format |
| * @return index of format or -1 if undefined. |
| */ |
| public static short getBuiltinFormat(String format) { |
| return (short) BuiltinFormats.getBuiltinFormat(format); |
| } |
| |
| /** |
| * Get the format index that matches the given format |
| * string, creating a new format entry if required. |
| * Aliases text to the proper format as required. |
| * @param pFormat string matching a built in format |
| * @return index of format. |
| */ |
| public short getFormat(String pFormat) { |
| // Normalise the format string |
| String format; |
| if (pFormat.equalsIgnoreCase("TEXT")) { |
| format = "@"; |
| } else { |
| format = pFormat; |
| } |
| |
| // Merge in the built in formats if we haven't already |
| if (!_movedBuiltins) { |
| for (int i=0; i<_builtinFormats.length; i++) { |
| ensureFormatsSize(i); |
| if (_formats.get(i) == null) { |
| _formats.set(i, _builtinFormats[i]); |
| } else { |
| // The workbook overrides this default format |
| } |
| } |
| _movedBuiltins = true; |
| } |
| |
| // See if we can find it |
| for(int i=0; i<_formats.size(); i++) { |
| if(format.equals(_formats.get(i))) { |
| return (short)i; |
| } |
| } |
| |
| // We can't find it, so add it as a new one |
| short index = _workbook.getFormat(format, true); |
| ensureFormatsSize(index); |
| _formats.set(index, format); |
| return index; |
| } |
| |
| /** |
| * get the format string that matches the given format index |
| * @param index of a format |
| * @return string represented at index of format or null if there is not a format at that index |
| */ |
| public String getFormat(short index) { |
| if (_movedBuiltins) { |
| return _formats.get(index); |
| } |
| |
| if(index == -1) { |
| // YK: formatIndex can be -1, for example, for cell in column Y in test-data/spreadsheet/45322.xls |
| // return null for those |
| return null; |
| } |
| |
| String fmt = _formats.size() > index ? _formats.get(index) : null; |
| if (_builtinFormats.length > index && _builtinFormats[index] != null) { |
| // It's in the built in range |
| if (fmt != null) { |
| // It's been overriden, use that value |
| return fmt; |
| } else { |
| // Standard built in format |
| return _builtinFormats[index]; |
| } |
| } |
| return fmt; |
| } |
| |
| /** |
| * get the format string that matches the given format index |
| * @param index of a built in format |
| * @return string represented at index of format or null if there is not a builtin format at that index |
| */ |
| public static String getBuiltinFormat(short index) { |
| return BuiltinFormats.getBuiltinFormat(index); |
| } |
| |
| /** |
| * get the number of built-in and reserved builtinFormats |
| * @return number of built-in and reserved builtinFormats |
| */ |
| public static int getNumberOfBuiltinBuiltinFormats() { |
| return _builtinFormats.length; |
| } |
| |
| /** |
| * Ensures that the formats list can hold entries |
| * up to and including the entry with this index |
| */ |
| private void ensureFormatsSize(int index) { |
| if(_formats.size() <= index) { |
| _formats.setSize(index+1); |
| } |
| } |
| } |