From f51b59e51e8ee973a00e3b2550df2330c1f686cd Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Sat, 25 Jun 2011 08:45:49 +0000 Subject: [PATCH] Bug 48877 - Fixed XSSFRichTextString to respect leading and trailing line breaks git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1139505 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 1 + .../xssf/usermodel/XSSFRichTextString.java | 16 +++-- .../usermodel/TestXSSFRichTextString.java | 64 +++++++++++++++++++ 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index edfcf676a..e5d7c1f29 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 48877 - Fixed XSSFRichTextString to respect leading and trailing line breaks 49564 - Fixed default behaviour of XSSFCellStyle.getLocked() 48314 - Fixed setting column and row breaks in XSSF 51424 - Ignore exceptions in ParagraphSprmUncompressor diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRichTextString.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRichTextString.java index 964e455e3..e3ed3223a 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRichTextString.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRichTextString.java @@ -440,17 +440,21 @@ public class XSSFRichTextString implements RichTextString { } /** - * Add the xml:spaces="preserve" attribute if the string has leading or trailing white spaces + * Add the xml:spaces="preserve" attribute if the string has leading or trailing spaces * * @param xs the string to check */ protected static void preserveSpaces(STXstring xs) { String text = xs.getStringValue(); - if (text != null && (text.startsWith(" ") || text.endsWith(" "))) { - XmlCursor c = xs.newCursor(); - c.toNextToken(); - c.insertAttributeWithValue(new QName("http://www.w3.org/XML/1998/namespace", "space"), "preserve"); - c.dispose(); + if (text != null && text.length() > 0) { + char firstChar = text.charAt(0); + char lastChar = text.charAt(text.length() - 1); + if(Character.isWhitespace(firstChar) || Character.isWhitespace(lastChar)) { + XmlCursor c = xs.newCursor(); + c.toNextToken(); + c.insertAttributeWithValue(new QName("http://www.w3.org/XML/1998/namespace", "space"), "preserve"); + c.dispose(); + } } } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRichTextString.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRichTextString.java index b53fe28fe..30f794882 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRichTextString.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRichTextString.java @@ -17,10 +17,14 @@ package org.apache.poi.xssf.usermodel; +import java.io.IOException; +import java.io.StringWriter; import java.util.TreeMap; import junit.framework.TestCase; +import org.apache.poi.POIXMLDocumentPart; +import org.apache.xmlbeans.XmlOptions; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXstring; @@ -290,4 +294,64 @@ public final class TestXSSFRichTextString extends TestCase { assertEquals("Apache", str.getCTRst().getRArray(0).getT()); assertEquals(" Software Foundation", str.getCTRst().getRArray(1).getT()); } + + public void testLineBreaks_bug48877() throws IOException{ + + XSSFFont font = new XSSFFont(); + font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD); + font.setFontHeightInPoints((short) 14); + XSSFRichTextString str; + STXstring t1, t2, t3; + + str = new XSSFRichTextString("Incorrect\nLine-Breaking"); + str.applyFont(0, 8, font); + t1 = str.getCTRst().getRList().get(0).xgetT(); + t2 = str.getCTRst().getRList().get(1).xgetT(); + assertEquals("Incorrec", t1.xmlText()); + assertEquals("t\nLine-Breaking", t2.xmlText()); + + str = new XSSFRichTextString("Incorrect\nLine-Breaking"); + str.applyFont(0, 9, font); + t1 = str.getCTRst().getRList().get(0).xgetT(); + t2 = str.getCTRst().getRList().get(1).xgetT(); + assertEquals("Incorrect", t1.xmlText()); + assertEquals("\nLine-Breaking", t2.xmlText()); + + str = new XSSFRichTextString("Incorrect\n Line-Breaking"); + str.applyFont(0, 9, font); + t1 = str.getCTRst().getRList().get(0).xgetT(); + t2 = str.getCTRst().getRList().get(1).xgetT(); + assertEquals("Incorrect", t1.xmlText()); + assertEquals("\n Line-Breaking", t2.xmlText()); + + str = new XSSFRichTextString("Tab\tseparated\n"); + t1 = str.getCTRst().xgetT(); + // trailing \n causes must be preserved + assertEquals("Tab\tseparated\n", t1.xmlText()); + + str.applyFont(0, 3, font); + t1 = str.getCTRst().getRList().get(0).xgetT(); + t2 = str.getCTRst().getRList().get(1).xgetT(); + assertEquals("Tab", t1.xmlText()); + assertEquals("\tseparated\n", t2.xmlText()); + + str = new XSSFRichTextString("Tab\tseparated\n"); + str.applyFont(0, 4, font); + t1 = str.getCTRst().getRList().get(0).xgetT(); + t2 = str.getCTRst().getRList().get(1).xgetT(); + // YK: don't know why, but XmlBeans converts leading tab characters to spaces + //assertEquals("Tab\t", t1.xmlText()); + assertEquals("separated\n", t2.xmlText()); + + str = new XSSFRichTextString("\n\n\nNew Line\n\n"); + str.applyFont(0, 3, font); + str.applyFont(11, 13, font); + t1 = str.getCTRst().getRList().get(0).xgetT(); + t2 = str.getCTRst().getRList().get(1).xgetT(); + t3 = str.getCTRst().getRList().get(2).xgetT(); + // YK: don't know why, but XmlBeans converts leading tab characters to spaces + assertEquals("\n\n\n", t1.xmlText()); + assertEquals("New Line", t2.xmlText()); + assertEquals("\n\n", t3.xmlText()); + } }