mirror of https://github.com/apache/poi.git
PR:17039 - DBCS chars in header and footer
Obtained from: kamoshida.toshiaki@future.co.jp Tweaked and tests added by self. git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353654 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f4059c7cc2
commit
90bc3e260a
|
@ -36,7 +36,8 @@ public class FooterRecord
|
|||
{
|
||||
public final static short sid = 0x15;
|
||||
private byte field_1_footer_len;
|
||||
private String field_2_footer;
|
||||
private byte field_2_unicode_flag;
|
||||
private String field_3_footer;
|
||||
|
||||
public FooterRecord()
|
||||
{
|
||||
|
@ -82,10 +83,45 @@ public class FooterRecord
|
|||
if (size > 0)
|
||||
{
|
||||
field_1_footer_len = data[ 0 + offset ];
|
||||
field_2_footer = StringUtil.getFromCompressedUnicode(data, 3 + offset, // [Shawn] Changed 1 to 3 for offset of string
|
||||
field_2_unicode_flag = data[ 2 + offset ];
|
||||
if(isMultibyte())
|
||||
{
|
||||
field_3_footer = StringUtil.getFromUnicodeLE(
|
||||
data,3 + offset,LittleEndian.ubyteToInt(field_1_footer_len));
|
||||
}
|
||||
else
|
||||
{
|
||||
field_3_footer = new String(data, 3 + offset, // [Shawn] Changed 1 to 3 for offset of string
|
||||
LittleEndian.ubyteToInt( field_1_footer_len) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* see the unicode flag
|
||||
*
|
||||
* @return boolean flag
|
||||
* true:footer string has at least one multibyte character
|
||||
*/
|
||||
public boolean isMultibyte() {
|
||||
return ((field_2_unicode_flag & 0xFF) == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* check the parameter has multibyte character
|
||||
*
|
||||
* @param value string to check
|
||||
* @return boolean result
|
||||
* true:string has at least one multibyte character
|
||||
*/
|
||||
private static boolean hasMultibyte(String value){
|
||||
if( value == null )return false;
|
||||
for(int i = 0 ; i < value.length() ; i++ ){
|
||||
char c = value.charAt(i);
|
||||
if(c > 0xFF )return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the length of the footer string
|
||||
|
@ -108,7 +144,9 @@ public class FooterRecord
|
|||
|
||||
public void setFooter(String footer)
|
||||
{
|
||||
field_2_footer = footer;
|
||||
field_3_footer = footer;
|
||||
field_2_unicode_flag =
|
||||
(byte) (hasMultibyte(field_3_footer) ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,7 +170,7 @@ public class FooterRecord
|
|||
|
||||
public String getFooter()
|
||||
{
|
||||
return field_2_footer;
|
||||
return field_3_footer;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
|
@ -156,14 +194,24 @@ public class FooterRecord
|
|||
{
|
||||
len+=3; // [Shawn] Fixed for two null bytes in the length
|
||||
}
|
||||
short bytelen = (short)(isMultibyte() ?
|
||||
getFooterLength()*2 : getFooterLength() );
|
||||
LittleEndian.putShort(data, 0 + offset, sid);
|
||||
LittleEndian.putShort(data, 2 + offset,
|
||||
( short ) ((len - 4) + getFooterLength()));
|
||||
( short ) ((len - 4) + bytelen ));
|
||||
if (getFooterLength() > 0)
|
||||
{
|
||||
data[ 4 + offset ] = (byte)getFooterLength();
|
||||
data[ 6 + offset ] = field_2_unicode_flag;
|
||||
if(isMultibyte())
|
||||
{
|
||||
StringUtil.putUnicodeLE(getFooter(), data, 7 + offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
StringUtil.putCompressedUnicode(getFooter(), data, 7 + offset); // [Shawn] Place the string in the correct offset
|
||||
}
|
||||
}
|
||||
return getRecordSize();
|
||||
}
|
||||
|
||||
|
@ -175,7 +223,8 @@ public class FooterRecord
|
|||
{
|
||||
retval+=3; // [Shawn] Fixed for two null bytes in the length
|
||||
}
|
||||
return retval + getFooterLength();
|
||||
return (isMultibyte() ?
|
||||
(retval + getFooterLength()*2) : (retval + getFooterLength()));
|
||||
}
|
||||
|
||||
public short getSid()
|
||||
|
@ -186,7 +235,8 @@ public class FooterRecord
|
|||
public Object clone() {
|
||||
FooterRecord rec = new FooterRecord();
|
||||
rec.field_1_footer_len = field_1_footer_len;
|
||||
rec.field_2_footer = field_2_footer;
|
||||
rec.field_2_unicode_flag = field_2_unicode_flag;
|
||||
rec.field_3_footer = field_3_footer;
|
||||
return rec;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,8 @@ public class HeaderRecord
|
|||
{
|
||||
public final static short sid = 0x14;
|
||||
private byte field_1_header_len;
|
||||
private String field_2_header;
|
||||
private byte field_2_unicode_flag;
|
||||
private String field_3_header;
|
||||
|
||||
public HeaderRecord()
|
||||
{
|
||||
|
@ -82,9 +83,44 @@ public class HeaderRecord
|
|||
if (size > 0)
|
||||
{
|
||||
field_1_header_len = data[ 0 + offset ];
|
||||
field_2_header = StringUtil.getFromCompressedUnicode(data, 3 + offset, // [Shawn] Changed 1 to 3 for offset of string
|
||||
LittleEndian.ubyteToInt(field_1_header_len));
|
||||
field_2_unicode_flag = data[ 2 + offset ];
|
||||
if(isMultibyte())
|
||||
{
|
||||
field_3_header = StringUtil.getFromUnicodeLE(
|
||||
data,3 + offset,LittleEndian.ubyteToInt(field_1_header_len));
|
||||
}
|
||||
else
|
||||
{
|
||||
field_3_header = new String(data, 3 + offset, // [Shawn] Changed 1 to 3 for offset of string
|
||||
LittleEndian.ubyteToInt( field_1_header_len) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* see the unicode flag
|
||||
*
|
||||
* @return boolean flag
|
||||
* true:footer string has at least one multibyte character
|
||||
*/
|
||||
public boolean isMultibyte() {
|
||||
return ((field_2_unicode_flag & 0xFF) == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* check the parameter has multibyte character
|
||||
*
|
||||
* @param value string to check
|
||||
* @return boolean result
|
||||
* true:string has at least one multibyte character
|
||||
*/
|
||||
private static boolean hasMultibyte(String value){
|
||||
if( value == null )return false;
|
||||
for(int i = 0 ; i < value.length() ; i++ ){
|
||||
char c = value.charAt(i);
|
||||
if(c > 0xFF )return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,7 +144,9 @@ public class HeaderRecord
|
|||
|
||||
public void setHeader(String header)
|
||||
{
|
||||
field_2_header = header;
|
||||
field_3_header = header;
|
||||
field_2_unicode_flag =
|
||||
(byte) (hasMultibyte(field_3_header) ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,7 +170,7 @@ public class HeaderRecord
|
|||
|
||||
public String getHeader()
|
||||
{
|
||||
return field_2_header;
|
||||
return field_3_header;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
|
@ -156,15 +194,25 @@ public class HeaderRecord
|
|||
{
|
||||
len+=3; // [Shawn] Fixed for two null bytes in the length
|
||||
}
|
||||
short bytelen = (short)(isMultibyte() ?
|
||||
getHeaderLength()*2 : getHeaderLength() );
|
||||
LittleEndian.putShort(data, 0 + offset, sid);
|
||||
LittleEndian.putShort(data, 2 + offset,
|
||||
( short ) ((len - 4) + getHeaderLength()));
|
||||
( short ) ((len - 4) + bytelen));
|
||||
|
||||
if (getHeaderLength() > 0)
|
||||
{
|
||||
data[ 4 + offset ] = (byte)getHeaderLength();
|
||||
data[ 6 + offset ] = field_2_unicode_flag;
|
||||
if(isMultibyte())
|
||||
{
|
||||
StringUtil.putUnicodeLE(getHeader(), data, 7 + offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
StringUtil.putCompressedUnicode(getHeader(), data, 7 + offset); // [Shawn] Place the string in the correct offset
|
||||
}
|
||||
}
|
||||
return getRecordSize();
|
||||
}
|
||||
|
||||
|
@ -176,8 +224,8 @@ public class HeaderRecord
|
|||
{
|
||||
retval+=3; // [Shawn] Fixed for two null bytes in the length
|
||||
}
|
||||
retval += getHeaderLength();
|
||||
return retval;
|
||||
return (isMultibyte() ?
|
||||
(retval + getHeaderLength()*2) : (retval + getHeaderLength()));
|
||||
}
|
||||
|
||||
public short getSid()
|
||||
|
@ -188,7 +236,8 @@ public class HeaderRecord
|
|||
public Object clone() {
|
||||
HeaderRecord rec = new HeaderRecord();
|
||||
rec.field_1_header_len = field_1_header_len;
|
||||
rec.field_2_header = field_2_header;
|
||||
rec.field_2_unicode_flag = field_2_unicode_flag;
|
||||
rec.field_3_header = field_3_header;
|
||||
return rec;
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -24,6 +24,8 @@ import org.apache.poi.hssf.usermodel.HSSFFooter;
|
|||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
@ -86,5 +88,65 @@ public class TestHSSFHeaderFooter extends TestCase {
|
|||
assertEquals("Bottom Center", foot.getCenter());
|
||||
assertEquals("Bottom Right", foot.getRight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Testcase for Bug 17039 HSSFHeader doesnot support DBCS
|
||||
*/
|
||||
public void testHeaderHas16bitCharacter() throws Exception {
|
||||
HSSFWorkbook b = new HSSFWorkbook();
|
||||
HSSFSheet s = b.createSheet("Test");
|
||||
HSSFHeader h = s.getHeader();
|
||||
h.setLeft("\u0391");
|
||||
h.setCenter("\u0392");
|
||||
h.setRight("\u0393");
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
b.write(out);
|
||||
|
||||
HSSFWorkbook b2 = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray()));
|
||||
HSSFHeader h2 = b2.getSheet("Test").getHeader();
|
||||
|
||||
assertEquals(h2.getLeft(),"\u0391");
|
||||
assertEquals(h2.getCenter(),"\u0392");
|
||||
assertEquals(h2.getRight(),"\u0393");
|
||||
}
|
||||
|
||||
/**
|
||||
* Testcase for Bug 17039 HSSFFooter doesnot support DBCS
|
||||
*/
|
||||
public void testFooterHas16bitCharacter() throws Exception{
|
||||
HSSFWorkbook b = new HSSFWorkbook();
|
||||
HSSFSheet s = b.createSheet("Test");
|
||||
HSSFFooter f = s.getFooter();
|
||||
f.setLeft("\u0391");
|
||||
f.setCenter("\u0392");
|
||||
f.setRight("\u0393");
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
b.write(out);
|
||||
|
||||
HSSFWorkbook b2 = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray()));
|
||||
HSSFFooter f2 = b2.getSheet("Test").getFooter();
|
||||
|
||||
assertEquals(f2.getLeft(),"\u0391");
|
||||
assertEquals(f2.getCenter(),"\u0392");
|
||||
assertEquals(f2.getRight(),"\u0393");
|
||||
}
|
||||
|
||||
public void testReadDBCSHeaderFooter() throws Exception{
|
||||
String readFilename = System.getProperty("HSSF.testdata.path");
|
||||
FileInputStream in = new FileInputStream(readFilename+File.separator+"DBCSHeader.xls");
|
||||
HSSFWorkbook wb = new HSSFWorkbook(in);
|
||||
HSSFSheet s = wb.getSheetAt(0);
|
||||
HSSFHeader h = s.getHeader();
|
||||
assertEquals("Header Left " ,h.getLeft(),"\u090f\u0915");
|
||||
assertEquals("Header Center " ,h.getCenter(),"\u0939\u094b\u0917\u093e");
|
||||
assertEquals("Header Right " ,h.getRight(),"\u091c\u093e");
|
||||
|
||||
HSSFFooter f = s.getFooter();
|
||||
assertEquals("Footer Left " ,f.getLeft(),"\u091c\u093e");
|
||||
assertEquals("Footer Center " ,f.getCenter(),"\u091c\u093e");
|
||||
assertEquals("Footer Right " ,f.getRight(),"\u091c\u093e");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue