From b57336834be0665f77119766c383f667cce26a5f Mon Sep 17 00:00:00 2001 From: Jason Height Date: Tue, 3 Jan 2006 11:41:36 +0000 Subject: [PATCH] Fixes to Unicode support. Believe that most unicode issues are now fixed. Bug 37622 & Bug 22873 squashed. git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@365609 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/hssf/model/Workbook.java | 15 ++- .../poi/hssf/record/formula/StringPtg.java | 4 +- .../apache/poi/hssf/usermodel/HSSFCell.java | 31 +++--- .../poi/hssf/usermodel/HSSFWorkbook.java | 24 ++++- .../poi/hssf/record/TestBoundSheetRecord.java | 5 +- .../poi/hssf/usermodel/TestHSSFWorkbook.java | 6 +- .../hssf/usermodel/TestUnicodeWorkbook.java | 95 +++++++++++++++++++ 7 files changed, 154 insertions(+), 26 deletions(-) create mode 100644 src/testcases/org/apache/poi/hssf/usermodel/TestUnicodeWorkbook.java diff --git a/src/java/org/apache/poi/hssf/model/Workbook.java b/src/java/org/apache/poi/hssf/model/Workbook.java index afb8e8039..6863f046c 100644 --- a/src/java/org/apache/poi/hssf/model/Workbook.java +++ b/src/java/org/apache/poi/hssf/model/Workbook.java @@ -457,10 +457,11 @@ public class Workbook implements Model * @param sheetnum the sheet number (0 based) * @param sheetname the name for the sheet */ - - // for compatibility public void setSheetName(int sheetnum, String sheetname ) { - setSheetName( sheetnum, sheetname, (byte)0 ); + checkSheets(sheetnum); + BoundSheetRecord sheet = (BoundSheetRecord)boundsheets.get( sheetnum ); + sheet.setSheetname(sheetname); + sheet.setSheetnameLength( (byte)sheetname.length() ); } /** @@ -481,6 +482,14 @@ public class Workbook implements Model return false; } + /** + * sets the name for a given sheet forcing the encoding. This is STILL A BAD IDEA. + * Poi now automatically detects unicode + * + *@deprecated 3-Jan-06 Simply use setSheetNam e(int sheetnum, String sheetname) + * @param sheetnum the sheet number (0 based) + * @param sheetname the name for the sheet + */ public void setSheetName(int sheetnum, String sheetname, short encoding ) { checkSheets(sheetnum); BoundSheetRecord sheet = (BoundSheetRecord)boundsheets.get( sheetnum ); diff --git a/src/java/org/apache/poi/hssf/record/formula/StringPtg.java b/src/java/org/apache/poi/hssf/record/formula/StringPtg.java index c15578610..96c5427c2 100644 --- a/src/java/org/apache/poi/hssf/record/formula/StringPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/StringPtg.java @@ -69,8 +69,8 @@ public class StringPtg if (value.length() >255) { throw new IllegalArgumentException("String literals in formulas cant be bigger than 255 characters ASCII"); } - this.field_2_options=0; - this.fHighByte.setBoolean(field_2_options, false); + this.field_2_options=0; + field_2_options = (byte)this.fHighByte.setBoolean(field_2_options, StringUtil.hasMultibyte(value)); this.field_3_string=value; this.field_1_length=value.length(); //for the moment, we support only ASCII strings in formulas we create } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index f7b97574a..c7822c266 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -381,13 +381,13 @@ public class HSSFCell int sst = 0; UnicodeString str = getRichStringCellValue().getUnicodeString(); - if (encoding == ENCODING_COMPRESSED_UNICODE) - { - str.setCompressedUnicode(); - } else if (encoding == ENCODING_UTF_16) - { - str.setUncompressedUnicode(); - } +//jmh if (encoding == ENCODING_COMPRESSED_UNICODE) +//jmh { +// jmh str.setCompressedUnicode(); +// jmh } else if (encoding == ENCODING_UTF_16) +// jmh { +// jmh str.setUncompressedUnicode(); +// jmh } sst = book.addSSTString(str); lrec.setSSTIndex(sst); getRichStringCellValue().setUnicodeString(book.getSSTString(sst)); @@ -572,13 +572,13 @@ public class HSSFCell int index = 0; UnicodeString str = value.getUnicodeString(); - if (encoding == ENCODING_COMPRESSED_UNICODE) - { - str.setCompressedUnicode(); - } else if (encoding == ENCODING_UTF_16) - { - str.setUncompressedUnicode(); - } +// jmh if (encoding == ENCODING_COMPRESSED_UNICODE) +// jmh { +// jmh str.setCompressedUnicode(); +// jmh } else if (encoding == ENCODING_UTF_16) +// jmh { +// jmh str.setUncompressedUnicode(); +// jmh } index = book.addSSTString(str); (( LabelSSTRecord ) record).setSSTIndex(index); stringValue = value; @@ -856,6 +856,8 @@ public class HSSFCell * @see #ENCODING_UTF_16 * * @return -1, 1 or 0 for unchanged, compressed or uncompressed (used only with String type) + * + * @deprecated As of 3-Jan-06 POI now automatically handles Unicode without forcing the encoding. */ public short getEncoding() { @@ -870,6 +872,7 @@ public class HSSFCell * @see #ENCODING_UTF_16 * * @param encoding either ENCODING_COMPRESSED_UNICODE (0) or ENCODING_UTF_16 (1) + * @deprecated As of 3-Jan-06 POI now automatically handles Unicode without forcing the encoding. */ public void setEncoding(short encoding) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index fe6559a8c..91b4683f5 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -339,7 +339,15 @@ public class HSSFWorkbook return workbook.getWindowOne().getDisplayedTab(); } + /** + * @deprecated POI will now properly handle unicode strings without + * forceing an encoding + */ public final static byte ENCODING_COMPRESSED_UNICODE = 0; + /** + * @deprecated POI will now properly handle unicode strings without + * forceing an encoding + */ public final static byte ENCODING_UTF_16 = 1; @@ -354,9 +362,23 @@ public class HSSFWorkbook if (workbook.doesContainsSheetName( name, sheet )) throw new IllegalArgumentException( "The workbook already contains a sheet with this name" ); - workbook.setSheetName( sheet, name, ENCODING_COMPRESSED_UNICODE ); + if (sheet > (sheets.size() - 1)) + { + throw new RuntimeException("Sheet out of bounds"); + } + + workbook.setSheetName( sheet, name); } + + /** + * set the sheet name forcing the encoding. Forcing the encoding IS A BAD IDEA!!! + * @deprecated 3-Jan-2006 POI now automatically detects unicode and sets the encoding + * appropriately. Simply use setSheetName(int sheet, String encoding) + * @throws IllegalArgumentException if the name is greater than 31 chars + * or contains /\?*[] + * @param sheet number (0 based) + */ public void setSheetName( int sheet, String name, short encoding ) { if (workbook.doesContainsSheetName( name, sheet )) diff --git a/src/testcases/org/apache/poi/hssf/record/TestBoundSheetRecord.java b/src/testcases/org/apache/poi/hssf/record/TestBoundSheetRecord.java index 6bb26c612..3843082fd 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestBoundSheetRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestBoundSheetRecord.java @@ -49,9 +49,8 @@ public class TestBoundSheetRecord public void testWideRecordLength() throws Exception { - BoundSheetRecord record = new BoundSheetRecord(); - record.setCompressedUnicodeFlag((byte)0x01); - record.setSheetname("Sheet1"); + BoundSheetRecord record = new BoundSheetRecord(); + record.setSheetname("Sheet\u20ac"); record.setSheetnameLength((byte)6); assertEquals(" 2 + 2 + 4 + 2 + 1 + 1 + len(str) * 2", 24, record.getRecordSize()); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java index e07fe2647..7bf6c4793 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java @@ -46,15 +46,15 @@ public class TestHSSFWorkbook extends TestCase try { - b.setSheetName( 3, "name1", HSSFWorkbook.ENCODING_UTF_16 ); + b.setSheetName( 3, "name1"/*JMH, HSSFWorkbook.ENCODING_UTF_16*/ ); fail(); } catch ( IllegalArgumentException pass ) { } - b.setSheetName( 3, "name2", HSSFWorkbook.ENCODING_UTF_16 ); - b.setSheetName( 3, "name2", HSSFWorkbook.ENCODING_UTF_16 ); + b.setSheetName( 3, "name2"/*JMH, HSSFWorkbook.ENCODING_UTF_16*/ ); + b.setSheetName( 3, "name2"/*JMH, HSSFWorkbook.ENCODING_UTF_16*/ ); b.setSheetName( 3, "name2" ); HSSFWorkbook c = new HSSFWorkbook( ); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestUnicodeWorkbook.java b/src/testcases/org/apache/poi/hssf/usermodel/TestUnicodeWorkbook.java new file mode 100644 index 000000000..5eda00eff --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestUnicodeWorkbook.java @@ -0,0 +1,95 @@ +package org.apache.poi.hssf.usermodel; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileInputStream; + +import org.apache.poi.util.TempFile; + +import junit.framework.TestCase; + +public class TestUnicodeWorkbook extends TestCase { + + public TestUnicodeWorkbook(String s) { + super(s); + } + + /** Tests that all of the unicode capable string fields can be set, written and then read back + * + * + */ + public void testUnicodeInAll() throws Exception { + HSSFWorkbook wb = new HSSFWorkbook(); + //Create a unicode dataformat (contains euro symbol) + HSSFDataFormat df = wb.createDataFormat(); + final String formatStr = "_([$\u20ac-2]\\\\\\ * #,##0.00_);_([$\u20ac-2]\\\\\\ * \\\\\\(#,##0.00\\\\\\);_([$\u20ac-2]\\\\\\ *\\\"\\-\\\\\"??_);_(@_)"; + short fmt = df.getFormat(formatStr); + + //Create a unicode sheet name (euro symbol) + HSSFSheet s = wb.createSheet("\u20ac"); + + //Set a unicode header (you guessed it the euro symbol) + HSSFHeader h = s.getHeader(); + h.setCenter("\u20ac"); + h.setLeft("\u20ac"); + h.setRight("\u20ac"); + + //Set a unicode footer + HSSFFooter f = s.getFooter(); + f.setCenter("\u20ac"); + f.setLeft("\u20ac"); + f.setRight("\u20ac"); + + HSSFRow r = s.createRow(0); + HSSFCell c = r.createCell((short)1); + c.setCellValue(12.34); + c.getCellStyle().setDataFormat(fmt); + + HSSFCell c2 = r.createCell((short)2); + c.setCellValue(new HSSFRichTextString("\u20ac")); + + HSSFCell c3 = r.createCell((short)3); + String formulaString = "TEXT(12.34,\"\u20ac###,##\")"; + c3.setCellFormula(formulaString); + + + File tempFile = TempFile.createTempFile("unicode", "test.xls"); + FileOutputStream stream = new FileOutputStream(tempFile); + wb.write(stream); + + wb = null; + FileInputStream in = new FileInputStream(tempFile); + wb = new HSSFWorkbook(in); + + //Test the sheetname + s = wb.getSheet("\u20ac"); + assertNotNull(s); + + //Test the header + h = s.getHeader(); + assertEquals(h.getCenter(), "\u20ac"); + assertEquals(h.getLeft(), "\u20ac"); + assertEquals(h.getRight(), "\u20ac"); + + //Test the footer + f = s.getFooter(); + assertEquals(f.getCenter(), "\u20ac"); + assertEquals(f.getLeft(), "\u20ac"); + assertEquals(f.getRight(), "\u20ac"); + + //Test the dataformat + r = s.getRow(0); + c = r.getCell((short)1); + df = wb.createDataFormat(); + assertEquals(formatStr, df.getFormat(c.getCellStyle().getDataFormat())); + + //Test the cell string value + c2 = r.getCell((short)2); + assertEquals(c.getRichStringCellValue().getString(), "\u20ac"); + + //Test the cell formula + c3 = r.getCell((short)3); + assertEquals(c3.getCellFormula(), formulaString); + } + +}