diff --git a/src/java/org/apache/poi/hssf/record/ExtendedFormatRecord.java b/src/java/org/apache/poi/hssf/record/ExtendedFormatRecord.java
index 261cfd878..6f64d46ec 100644
--- a/src/java/org/apache/poi/hssf/record/ExtendedFormatRecord.java
+++ b/src/java/org/apache/poi/hssf/record/ExtendedFormatRecord.java
@@ -410,7 +410,7 @@ public final class ExtendedFormatRecord
}
/**
- * set the degree of rotation. (I've not actually seen this used anywhere)
+ * set the degree of rotation.
*
*
* @param rotation the degree of rotation
@@ -1145,7 +1145,7 @@ public final class ExtendedFormatRecord
}
/**
- * get the degree of rotation. (I've not actually seen this used anywhere)
+ * get the degree of rotation.
*
*
* @return rotation - the degree of rotation
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
index b6d366c50..25e3b371c 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
@@ -324,6 +324,12 @@ public final class HSSFCellStyle implements CellStyle {
/**
* set the degree of rotation for the text in the cell
+ *
+ * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF
+ * uses values from 0 to 180 degrees. The implementations of this method will map between these two value-ranges
+ * accordingly, however the corresponding getter is returning values in the range mandated by the current type
+ * of Excel file-format that this CellStyle is applied to.
+ *
* @param rotation degrees (between -90 and 90 degrees, of 0xff for vertical)
*/
@Override
@@ -337,7 +343,11 @@ public final class HSSFCellStyle implements CellStyle {
//The 4th quadrant (-1 to -90) is stored as (91 to 180)
rotation = (short)(90 - rotation);
}
- else if ((rotation < -90) ||(rotation > 90)) {
+ else if (rotation > 90 && rotation <= 180) {
+ // stay compatible with the range used by XSSF, map from ]90..180] to ]0..-90]
+ // we actually don't need to do anything here as the internal value is stored in [0-180] anyway!
+ }
+ else if ((rotation < -90) || (rotation > 90)) {
//Do not allow an incorrect rotation to be set
throw new IllegalArgumentException("The rotation must be between -90 and 90 degrees, or 0xff");
}
diff --git a/src/java/org/apache/poi/ss/usermodel/CellStyle.java b/src/java/org/apache/poi/ss/usermodel/CellStyle.java
index be5a43e93..e91d19d0f 100644
--- a/src/java/org/apache/poi/ss/usermodel/CellStyle.java
+++ b/src/java/org/apache/poi/ss/usermodel/CellStyle.java
@@ -363,17 +363,26 @@ public interface CellStyle {
short getVerticalAlignment();
/**
- * set the degree of rotation for the text in the cell
- * @param rotation degrees (between -90 and 90 degrees)
+ * set the degree of rotation for the text in the cell.
+ *
+ * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF
+ * uses values from 0 to 180 degrees. The implementations of this method will map between these two value-ranges
+ * accordingly, however the corresponding getter is returning values in the range mandated by the current type
+ * of Excel file-format that this CellStyle is applied to.
+ *
+ * @param rotation degrees (see note above)
*/
-
void setRotation(short rotation);
/**
- * get the degree of rotation for the text in the cell
- * @return rotation degrees (between -90 and 90 degrees)
+ * get the degree of rotation for the text in the cell.
+ *
+ * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF
+ * uses values from 0 to 180 degrees. The implementations of this method will map between these two value-ranges
+ * value-range as used by the type of Excel file-format that this CellStyle is applied to.
+ *
+ * @return rotation degrees (see note above)
*/
-
short getRotation();
/**
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java
index a2c265f1b..ea355756e 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java
@@ -1364,6 +1364,11 @@ public void setFillPattern(short fp) {
* [degrees below horizon] = 90 - textRotation.
*
[degrees below horizon] = 90 - textRotation.
*
*
+ * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF
+ * uses values from 0 to 180 degrees. The implementations of this method will map between these two value-ranges
+ * accordingly, however the corresponding getter is returning values in the range mandated by the current type
+ * of Excel file-format that this CellStyle is applied to.
+ *
* @param rotation - the rotation degrees (between 0 and 180 degrees)
*/
public void setTextRotation(long rotation) {
+ if(rotation < 0 && rotation >= -90) {
+ rotation = 90 + ((-1)*rotation);
+ }
cellAlignement.setTextRotation(rotation);
}
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java
index 56eff4457..92235c439 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java
@@ -2906,4 +2906,52 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
wb.close();
}
+
+ private void createXls() throws IOException
+ {
+ Workbook workbook = new HSSFWorkbook();
+ FileOutputStream fileOut = new FileOutputStream("/tmp/rotated.xls");
+ Sheet sheet1 = workbook.createSheet();
+ Row row1 = sheet1.createRow((short) 0);
+
+ Cell cell1 = row1.createCell(0);
+
+ cell1.setCellValue("Successful rotated text.");
+
+ CellStyle style = workbook.createCellStyle();
+ style.setRotation((short) -90);
+
+ cell1.setCellStyle(style);
+
+ workbook.write(fileOut);
+ fileOut.close();
+ workbook.close();
+ }
+
+ private void createXlsx() throws IOException {
+ Workbook workbook = new XSSFWorkbook();
+ FileOutputStream fileOut = new FileOutputStream("/tmp/rotated.xlsx");
+ Sheet sheet1 = workbook.createSheet();
+ Row row1 = sheet1.createRow((short) 0);
+
+ Cell cell1 = row1.createCell(0);
+
+ cell1.setCellValue("Unsuccessful rotated text.");
+
+ CellStyle style = workbook.createCellStyle();
+ style.setRotation((short) -90);
+
+ cell1.setCellStyle(style);
+
+ workbook.write(fileOut);
+ fileOut.close();
+ workbook.close();
+ }
+
+ @Ignore("Creates files for checking results manually, actual values are tested in Test*CellStyle")
+ @Test
+ public void test58043() throws Exception {
+ createXls();
+ createXlsx();
+ }
}
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java
index 1b33f28a4..21f14bb5d 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java
@@ -1059,4 +1059,31 @@ public class TestXSSFCellStyle {
target.close();
reference.close();
}
+
+ @Test
+ public void test58043() {
+ assertEquals(0, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)89);
+ assertEquals(89, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)90);
+ assertEquals(90, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)179);
+ assertEquals(179, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)180);
+ assertEquals(180, cellStyle.getRotation());
+
+ // negative values are mapped to the correct values for compatibility between HSSF and XSSF
+ cellStyle.setRotation((short)-1);
+ assertEquals(91, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)-89);
+ assertEquals(179, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)-90);
+ assertEquals(180, cellStyle.getRotation());
+ }
}
diff --git a/src/testcases/org/apache/poi/hssf/record/TestExtendedFormatRecord.java b/src/testcases/org/apache/poi/hssf/record/TestExtendedFormatRecord.java
index 6aaa509a5..5ed16ad0f 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestExtendedFormatRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestExtendedFormatRecord.java
@@ -129,4 +129,28 @@ public final class TestExtendedFormatRecord extends TestCase {
for (int i = 0; i < data.length; i++)
assertEquals("At offset " + i, data[i], recordBytes[i + 4]);
}
+
+ public void testRotation() {
+ ExtendedFormatRecord record = createEFR();
+ assertEquals(0, record.getRotation());
+
+ record.setRotation((short)1);
+ assertEquals(1, record.getRotation());
+
+ record.setRotation((short)89);
+ assertEquals(89, record.getRotation());
+
+ record.setRotation((short)90);
+ assertEquals(90, record.getRotation());
+
+ // internally values below zero are stored differently
+ record.setRotation((short)-1);
+ assertEquals(255, record.getRotation());
+
+ record.setRotation((short)-89);
+ assertEquals(-77, 90-record.getRotation());
+
+ record.setRotation((short)-90);
+ assertEquals(-76, 90-record.getRotation());
+ }
}
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java b/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java
index 002803486..8d7fd012a 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java
@@ -23,8 +23,6 @@ import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
-import junit.framework.TestCase;
-
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
@@ -34,6 +32,9 @@ import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.TempFile;
+import org.junit.Test;
+
+import junit.framework.TestCase;
/**
* Class to test cell styling functionality
@@ -507,4 +508,40 @@ public final class TestCellStyle extends TestCase {
// out.close();
// }
}
+
+
+ @Test
+ public void test58043() throws IOException {
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFCellStyle cellStyle = wb.createCellStyle();
+
+ assertEquals(0, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)89);
+ assertEquals(89, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)90);
+ assertEquals(90, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)-1);
+ assertEquals(-1, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)-89);
+ assertEquals(-89, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)-90);
+ assertEquals(-90, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)-89);
+ assertEquals(-89, cellStyle.getRotation());
+
+ // values above 90 are mapped to the correct values for compatibility between HSSF and XSSF
+ cellStyle.setRotation((short)179);
+ assertEquals(-89, cellStyle.getRotation());
+
+ cellStyle.setRotation((short)180);
+ assertEquals(-90, cellStyle.getRotation());
+
+ wb.close();
+ }
}