Right to Left (RTL) text in XWPFDocument (Apache POI) - apache-poi

I could not find a way to make a RTL paragraph in Docx using XWPFDocument (Apache POI) in my Java program. Here's my code that generates the XWPFDocument.
XWPFParagraph title = document.createParagraph();
title.setAlignment(ParagraphAlignment.CENTER);
title.setVerticalAlignment(TextAlignment.CENTER);
title.setWordWrap(true);
XWPFRun titleRun = title.createRun();
titleRun.setText(reportDesign.getName());
XWPFTable s = document.createTable(resultList.size()+1, columnList.size());
// declare a row object reference
XWPFTableRow r = s.getRow(0);
// declare a cell object reference
XWPFTableCell c = null;
// create columnList.size() cells (0-(columnList.size()-1))
for (int cellnum = 0; cellnum < columnList.size(); cellnum++) {
c = r.getCell(cellnum);
c.setColor("c9c9c9");
c.setVerticalAlignment(XWPFVertAlign.CENTER);
c.setText(columnList.get(cellnum).getColumnHeader());
}
// create a sheet with resultList.size() rows (1-resultList.size())
for (int rownum = 0; rownum < resultList.size(); rownum++) {
// create a row
r = s.getRow(rownum+1);
// create columnList.size() cells (0-(columnList.size()-1))
for (int cellnum = 0; cellnum < columnList.size(); cellnum++) {
c = r.getCell(cellnum);
Object value = resultList.get(rownum).get(columnList.get(cellnum).getColumnKey());
if (value != null) {
c.setText(value.toString());
} else {
c.setText("");
}
}
}
Would you please help me? Is there a logical way to extend POI (or similar solution) for gaining this feature?

A workaround that I found till now is using a template document.
Using this method, you make an empty document that "Normal" style in it, is configured to be RTL. This way, everything in your document will be RTL.
XWPFDocument document = new XWPFDocument(AbstractWordView.class.getClassLoader().getResourceAsStream("empty.docx"));

Related

how to update ext list value of pptx scatter chart

Read pptx template then use new data to replace it, there is a scatter chart
associated excel data
xVal and yVal could replace successfully but how to replace C column (extList) ?
xVal and yVal replace by below manner
final CTScatterSer ser = serList.get(0);
final CTAxDataSource xVal = ser.getXVal();
final CTNumDataSource yVal = ser.getYVal();
final CTExtension ctExtension = ser.getExtLst().getExtList().get(0);
final long ptCount = xVal.getNumRef().getNumCache().getPtCount().getVal();
for (int i = 0; i < scData.size(); i++) {
SCNameDouble data = scData.get(i);
CTNumVal xNumVal = ptCount > i ? xVal.getNumRef().getNumCache().getPtArray(i)
: xVal.getNumRef().getNumCache().addNewPt();
xNumVal.setIdx(i);
xNumVal.setV(String.format("%.2f", data.xValue));
CTNumVal yNumVal = ptCount > i ? yVal.getNumRef().getNumCache().getPtArray(i)
: yVal.getNumRef().getNumCache().addNewPt();
yNumVal.setIdx(i);
yNumVal.setV(String.format("%.2f", data.yValue));
}
final int newSize = scData.size();
xVal.getNumRef().setF(
replaceRowEnd(xVal.getNumRef().getF(),
ptCount,
newSize));
yVal.getNumRef().setF(
replaceRowEnd(yVal.getNumRef().getF(),
ptCount,
newSize));
xVal.getNumRef().getNumCache().getPtCount().setVal(newSize);
yVal.getNumRef().getNumCache().getPtCount().setVal(newSize);
Using current apache poi versions one should not trying manipulating charts using the low level CT... classes. There is XDDF for such cases now.
If it comes to PowerPoint charts, then the need is always updating the data in the embedded workbook and updating the data in the chart. See Java edit bar chart in ppt by using poi for an example using bar chart.
Of course a scatter chart is another case then as it not has a category axis but has two value axes. But this also can be updated using XDDF.
The biggest problem you have is the data labels. There is not full support for chart data labels in XDDF upto now. And since you are talkig about extLst and your Excel table shows the data labels in a cell range, I suspect you have set the data labels comming from a cell range. This is a new feature which was not present when Microsoft had published Office Open XML. So not even the low level CT... classes are able to support that feature.
The only way is to manipulate the XML using pure XML manupulating based on org.apache.xmlbeans.XmlObject.
The following shows this on sample of a template you seems to use according to your question.
ScatterChartSample.pptx:
Code:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.AreaReference;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumns;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
public class PowerPointChangeScatterChartData {
//patched version of XSSFTable.updateHeaders, see https://stackoverflow.com/questions/55532006/renaming-headers-of-xssftable-with-apache-poi-leads-to-corrupt-xlsx-file/55539181#55539181
static void updateHeaders(XSSFTable table) {
XSSFSheet sheet = (XSSFSheet)table.getParent();
CellReference ref = table.getStartCellReference();
if (ref == null) return;
int headerRow = ref.getRow();
int firstHeaderColumn = ref.getCol();
XSSFRow row = sheet.getRow(headerRow);
DataFormatter formatter = new DataFormatter();
if (row != null /*&& row.getCTRow().validate()*/) {
int cellnum = firstHeaderColumn;
CTTableColumns ctTableColumns = table.getCTTable().getTableColumns();
if(ctTableColumns != null) {
for (CTTableColumn col : ctTableColumns.getTableColumnList()) {
XSSFCell cell = row.getCell(cellnum);
if (cell != null) {
col.setName(formatter.formatCellValue(cell));
}
cellnum++;
}
}
}
}
static void updateScatterChart(XSLFChart chart, Object[][] data) throws Exception {
// get chart's data source which is a Excel sheet
XSSFWorkbook chartDataWorkbook = chart.getWorkbook();
String sheetName = chartDataWorkbook.getSheetName(0);
XSSFSheet chartDataSheet = chartDataWorkbook.getSheet(sheetName);
// current Office uses a table as data source
// so get that table if present
XSSFTable chartDataTable = null;
if (chartDataSheet.getTables().size() > 0) {
chartDataTable = chartDataSheet.getTables().get(0);
}
if (chart.getChartSeries().size() == 1) { // we will process only one chart data
XDDFChartData chartData = chart.getChartSeries().get(0);
if (chartData.getSeriesCount() == 1) { // we will process only templates having one series
int rMin = 1; // first row (0) is headers row
int rMax = data.length - 1;
// column 0 is X-Values
int c = 0;
// set new x data
XDDFDataSource xs = null;
for (int r = rMin; r <= rMax; r++) {
XSSFRow row = chartDataSheet.getRow(r); if (row == null) row = chartDataSheet.createRow(r);
XSSFCell cell = row.getCell(c); if (cell == null) cell = row.createCell(c);
cell.setCellValue((Double)data[r][c]); // in sheet
}
xs = XDDFDataSourcesFactory.fromNumericCellRange(chartDataSheet, new CellRangeAddress(rMin,rMax,c,c)); // in chart
// set new x-title in sheet
String xTitle = (String)data[0][c];
chartDataSheet.getRow(0).getCell(c).setCellValue(xTitle); // in sheet
// column 1 is Y-Values
c = 1;
// set new y data in sheet and in chart
XDDFNumericalDataSource<Double> ys = null;
for (int r = rMin; r <= rMax; r++) {
XSSFRow row = chartDataSheet.getRow(r); if (row == null) row = chartDataSheet.createRow(r);
XSSFCell cell = row.getCell(c); if (cell == null) cell = row.createCell(c);
cell.setCellValue((Double)data[r][c]); // in sheet
}
ys = XDDFDataSourcesFactory.fromNumericCellRange(chartDataSheet, new CellRangeAddress(rMin,rMax,c,c));
XDDFChartData.Series series1 = chartData.getSeries(0);
series1.replaceData(xs, ys); // in chart
// set new y-title in sheet and in chart
String yTitle = (String)data[0][c];
chartDataSheet.getRow(0).getCell(c).setCellValue(yTitle); // in sheet
series1.setTitle(yTitle, new CellReference(sheetName, 0, c, true, true)); // in chart
series1.plot();
// column 2 is data-labels-range
c = 2;
// set new data labels data in sheet and in chart
XDDFDataSource dataLabelsRangeSource = null;
for (int r = rMin; r <= rMax; r++) {
XSSFRow row = chartDataSheet.getRow(r); if (row == null) row = chartDataSheet.createRow(r);
XSSFCell cell = row.getCell(c); if (cell == null) cell = row.createCell(c);
cell.setCellValue((String)data[r][c]); // in sheet
}
dataLabelsRangeSource = XDDFDataSourcesFactory.fromStringCellRange(chartDataSheet, new CellRangeAddress(rMin,rMax,c,c)); // in chart
updateDataLabelsRange(chart, dataLabelsRangeSource); // in chart
// set new data-labels-title in sheet
String descrTitle = (String)data[0][c];
chartDataSheet.getRow(0).getCell(c).setCellValue(descrTitle); // in sheet
// update the table if present
if (chartDataTable != null) {
CellReference topLeft = new CellReference(chartDataSheet.getRow(0).getCell(0));
CellReference bottomRight = new CellReference(chartDataSheet.getRow(rMax).getCell(c));
AreaReference tableArea = chartDataWorkbook.getCreationHelper().createAreaReference(topLeft, bottomRight);
chartDataTable.setArea(tableArea);
updateHeaders(chartDataTable);
}
}
}
}
static void updateDataLabelsRange(XDDFChart chart, XDDFDataSource dataLabelsRangeSource) {
String declareNameSpaces = "declare namespace c='http://schemas.openxmlformats.org/drawingml/2006/chart'; "
+ "declare namespace c15='http://schemas.microsoft.com/office/drawing/2012/chart' ";
org.apache.xmlbeans.XmlObject[] selectedObjects = chart.getCTChart().selectPath(
declareNameSpaces
+ ".//c:ext[c15:datalabelsRange]"); // needs net.sf.saxon - Saxon-HE (Saxon-HE-10.6.jar)
if (selectedObjects.length > 0) { // we have at least one ext containing datalabelsRange
org.apache.xmlbeans.XmlObject ext = selectedObjects[0]; // get first ext containing datalabelsRange
// get dataLabelsRange
org.apache.xmlbeans.XmlObject[] datalabelsRanges = ext.selectChildren(new javax.xml.namespace.QName("http://schemas.microsoft.com/office/drawing/2012/chart", "datalabelsRange", "c15"));
org.apache.xmlbeans.XmlObject dataLabelsRange = datalabelsRanges[0];
// set formula
org.apache.xmlbeans.XmlObject[] formulas = dataLabelsRange.selectChildren(new javax.xml.namespace.QName("http://schemas.microsoft.com/office/drawing/2012/chart", "f", "c15"));
org.apache.xmlbeans.XmlObject formula = formulas[0];
((org.apache.xmlbeans.impl.values.XmlObjectBase)formula).setStringValue(dataLabelsRangeSource.getFormula());
// get dlblRangeCache
org.apache.xmlbeans.XmlObject[] dlblRangeCaches = dataLabelsRange.selectChildren(new javax.xml.namespace.QName("http://schemas.microsoft.com/office/drawing/2012/chart", "dlblRangeCache", "c15"));
org.apache.xmlbeans.XmlObject dlblRangeCache = dlblRangeCaches[0];
// empty the cache
dlblRangeCache.newCursor().removeXmlContents();
// create new cache from dataLabelsRangeSource
org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData cache = org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData.Factory.newInstance();
dataLabelsRangeSource.fillStringCache(cache);
// set new cache
dlblRangeCache.set(cache);
}
}
public static void main(String[] args) throws Exception {
String filePath = "ScatterChartSample.pptx"; // has template scatter chart
String filePathNew = "ScatterChartSample_New.pptx";
Object[][] data = new Object[][] { // new data 1 series, 6 x-y-values and data labels
{"X-Values", "Y-Values", "DataLabels"}, // series title
{0.7d, 1.7d, "aa"}, // x1
{1.8d, 3.2d, "bb"}, // x2
{2.6d, 2.8d, "cc"}, // x3
{1.7d, 3.7d, "dd"}, // x4
{2.8d, 4.2d, "ee"}, // x5
{3.6d, 1.8d, "ff"} // x6
};
XMLSlideShow slideShow = new XMLSlideShow(new FileInputStream(filePath));
XSLFChart chart = slideShow.getCharts().get(0);
updateScatterChart(chart, data);
FileOutputStream out = new FileOutputStream(filePathNew);
slideShow.write(out);
out.close();
slideShow.close();
}
}
Resulting ScatterChartSample_New.pptx:
Note: Tested and works using current apache poi 5.2.0.
To be able to use XPath as .//c:ext[c15:datalabelsRange] it needs net.sf.saxon - Saxon-HE (Saxon-HE-10.6.jar in my case).
And it needs poi-ooxml-full-5.2.0.jar and not only the lite version of ooxml-schemas.

Drop down's options don't appear when clicking arrow in excel exported with Apache POI when there are much cell comments

I export excel using Apache POI with drop down and many cell comments in it. When generating less cell comments, drop down's options appear for choosing when clicking drop down arrow, but when generating much cell comments, the drop down's options don't appear.
I do test with latest Apache POI version - 4.1.0.
HSSFWorkbook wb=new HSSFWorkbook();
HSSFSheet sheet=wb.createSheet("my sheet");
// create cell and add comments
int rowNum = 25;
int columnNum = 50;
HSSFPatriarch p=sheet.createDrawingPatriarch();
for (int i=0; i<rowNum; i++) {
HSSFRow row = sheet.createRow(i);
for (int j=0; j<columnNum; j++) {
HSSFCell cell = row.createCell(j);
cell.setCellValue(new HSSFRichTextString((i+1)+","+(j+1)));
if (i != 0 || j != 0) {
HSSFComment comment=p.createComment(new HSSFClientAnchor(0,0,0,0,(short)3,3,(short)5,6));
comment.setString(new HSSFRichTextString("comment for cell: " + (i+1) +","+(j+1)));
cell.setCellComment(comment);
}
}
}
// add drop down
String hiddenSheetName = "hiddenSheet";
HSSFSheet hiddenSheet = wb.createSheet(hiddenSheetName);
wb.setSheetHidden(wb.getSheetIndex(hiddenSheet), true);
HSSFRow hiddenRow = null;
HSSFCell hiddenCell = null;
String[] menuItems = {"Yes", "No"};
for (int i = 0; i < menuItems.length; i++)
{
hiddenRow = hiddenSheet.createRow(i);
hiddenCell = hiddenRow.createCell(0);
hiddenCell.setCellValue(menuItems[i]);
}
HSSFName namedCell = wb.createName();
String formulaId = "formulaId";
namedCell.setNameName(formulaId);
namedCell.setRefersToFormula(hiddenSheetName + "!A$1:A$" + menuItems.length);
HSSFDataValidationHelper dvHelper = new HSSFDataValidationHelper(sheet);
DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint(formulaId);
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
HSSFDataValidation validation = (HSSFDataValidation)dvHelper.createValidation(dvConstraint, addressList);
sheet.addValidationData(validation);
FileOutputStream out = null;
try{
out=new FileOutputStream("exportExcelTest.xls");
wb.write(out);
out.close();
} catch (Exception e) {
}
From my test result, when commenting out cell comments generation part, drop down's options appear for choosing when clicking drop down arrow and when setting variable rowNum to 15, the drop down's options also appear. When setting variable rowNum to 25, then it will generate much more cell comments, then drop down's options don't appear. And if setting rowNum to be greater than 25, options also don't appear. So I infer this problem is related to number of comments generated. I am not sure if this is an Apache POI issue or there is anything I write incorrectly in code. Hope someone can help me to figure out this problem.
These numbers I give to rowNum are just for test, you can give any rowNum to try.
I think it has nothing to do with the comments and the number of comments.
By using new CellRangeAddressList(0, 0, 0, 0) you apply the validation to exactly one cell (A1).
By changing it to new CellRangeAddressList(0, rowNum - 1, 0, columnNum - 1) you apply the validation to all the cells that are created.
The second thing you should change is your formula. Instead of !A$1:A$ you should write !$A$1:$A$.

Datagrid gives null values using for loop in WPF

I have a dataGrid with more than 100 rows in it. I am extracting it to an existing Excel file. I can open the file and add values to the sheet. My problem is, the value becomes null as soon as it gets to the 14th row.
I tried reversing the order of the data in the datagrid just to be sure that it's not the value or data in the dataGrid that is causing the issue but I still get the same result. Only the first 13 rows are extracted to the Excel sheet. The for loop still goes to the rest of the loop but it seems to not get the values.
Here is my code:
var path = #"D:\Reports\Sample.xlsx";
var excel = new Excel.Application {Visible = true};
var wb = excel.Workbooks.Open(path);
var ws = (Excel.Worksheet)wb.Sheets["summary"];
for (var i = 0; i < Grid.Columns.Count; i++)
{
for (int j = 0; j < Grid.Items.Count; j++)
{
var b = Grid.Columns[i].GetCellContent(Grid.Items[j]) as TextBlock; =====> ON THE 14th ROW, the "b" variable becomes null all throught out the for-loop
var myRange = (Range)ws.Cells[j + 2, i + 1];
try
{
if (b != null) myRange.Value2 = b.Text;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Thread.Sleep(100);
}
}
This is the Excel file created. Values are not extracted any more after the 14th row.

Error while opening PPT File generated by Apache POI

I am generating a powerpoint presentation using apache POI - XSLF, on the fly when the user clicks a certain link on my website. I have a few tables with data on my presentation file and also an image (Line chart) generated using jfreechart. When I open the PPTX on my machine it seems to work fine. However when I open the file on another machine that has the powerpoint 2013, I get the following error.
"powerpoint found a problem with content powerpoint can attempt to repair the presentation".
I want to get rid of this error. I read on the internet that the solution is to "UNBLOCK" the powerpoint, which can be done through the properties section of the file. I am wondering if there's something I can do programmatically to suppress this errors for my users. This error message is annoying at the least.
My last thread on this was deleted - https://stackoverflow.com/questions/41163148/how-to-unblock-pptx-using-apache-poi
Hence re-creating this thread here again. A bug is also entered in bugzilla for apache POI. Bug Id - 60633 (https://bz.apache.org/bugzilla/show_bug.cgi?id=60633).
XSLFTableCell cell
XSLFTextParagraph p
XSLFTextRun line
XSLFTable tbl = slide.createTable();
tbl.setAnchor(new Rectangle(X, Y, WIDTH, HEIGHT));
XSLFTableRow headerRow = tbl.addRow();
headerRow.setHeight(45);
//Loop through the data collection and populate rows and columns.
for(int i = 0; i < numberOfCols; i++) {
XSLFTableCell th = headerRow.addCell();
p = th.addNewTextParagraph();
p.setTextAlign(TextAlign.CENTER);
line = p.addNewTextRun();.....}
for (int item=0; item < 8; item++)
{
XSLFTableRow itemRow = tbl.addRow();.....}
//finally write the file
File pptFile = File.createTempFile("fileName", ".ppt")
FileOutputStream out = new FileOutputStream(pptFile)
ppt.write(out)
out.close()
If one provides code along with a bug report, then this code must be complete and verifiable. Your code is not complete and verifiable. And if i do completing it, then it works without problems.
import java.io.FileOutputStream;
import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.TableCell.BorderEdge;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import java.awt.Rectangle;
import java.awt.Point;
import java.awt.Color;
public class CreatePPTX {
public static void main(String[] args) throws Exception {
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide();
XSLFTableCell cell;
XSLFTextParagraph p;
XSLFTextRun line;
XSLFTable tbl = slide.createTable();
tbl.setAnchor(new Rectangle(new Point(100, 100)));
XSLFTableRow headerRow = tbl.addRow();
headerRow.setHeight(45);
for(int i = 0; i < 5; i++) {
XSLFTableCell th = headerRow.addCell();
p = th.addNewTextParagraph();
p.setTextAlign(TextAlign.CENTER);
line = p.addNewTextRun();
line.setText("Header " + i);
th.setBorderWidth(BorderEdge.bottom, 2.0);
th.setBorderColor(BorderEdge.bottom, Color.black);
}
for (int item=0; item < 8; item++) {
XSLFTableRow itemRow = tbl.addRow();
for (int i = 0; i < 5; i++) {
XSLFTableCell td = itemRow.addCell();
p = td.addNewTextParagraph();
p.setTextAlign(TextAlign.CENTER);
line = p.addNewTextRun();
line.setText("Cell " + item + ":" +i);
}
}
FileOutputStream out = new FileOutputStream("fileName.pptx");
ppt.write(out);
out.close();
}
}
So your problem is not reproducible using the code you have provided.
But one thing can lead to your issue. If cells shall be empty in the table, then do not create empty runs but let the cell totally empty.
Example with the above code, if cell 1:1 shall be empty, then do not:
...
for (int item=0; item < 8; item++) {
XSLFTableRow itemRow = tbl.addRow();
for (int i = 0; i < 5; i++) {
XSLFTableCell td = itemRow.addCell();
p = td.addNewTextParagraph();
p.setTextAlign(TextAlign.CENTER);
line = p.addNewTextRun();
if (!(item==1 && i==1)) {
line.setText("Cell " + item + ":" +i);
}
}
}
...
This leads to the error.
Instead do:
...
for (int item=0; item < 8; item++) {
XSLFTableRow itemRow = tbl.addRow();
for (int i = 0; i < 5; i++) {
XSLFTableCell td = itemRow.addCell();
p = td.addNewTextParagraph();
p.setTextAlign(TextAlign.CENTER);
if (!(item==1 && i==1)) {
line = p.addNewTextRun();
line.setText("Cell " + item + ":" +i);
}
}
}
...

How to override PrimeFaces p:dataExporter wrongly exporting numbers as text in Excel?

The PrimeFace p:dataExporter tag exports numeric data as text by default, which results in a cell with a green triangle in the upper left corner. This can be seen in the PrimeFaces showcase example as well, if you click the Excel export under the cars table.
How can I override this default to make sure my numeric columns are not exported as text? I tried using the postProcessor attribute pointing to my method that sets the Excel format for all the data cells using POI API but that did not take effect (did not change anything):
public void formatExcel(Object doc) {
HSSFWorkbook book = (HSSFWorkbook)doc;
HSSFSheet sheet = book.getSheetAt(0);
HSSFRow header = sheet.getRow(0);
int colCount = header.getPhysicalNumberOfCells();
int rowCount = sheet.getPhysicalNumberOfRows();
HSSFCellStyle numStyle = book.createCellStyle();
numStyle.setDataFormat((short)1);
for(int rowInd = 1; rowInd < rowCount; rowInd++) {
HSSFRow row = sheet.getRow(rowInd);
for(int cellInd = 1; cellInd < colCount; cellInd++) {
HSSFCell cell = row.getCell(cellInd);
String val = cell.getStringCellValue();
cell.setCellStyle(numStyle);
}
}
}
I also tried
cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
but that gives me
java.lang.IllegalStateException: Cannot get a numeric value from a text cell
So that means that all data is indiscriminately exported as text and then you can't even change it afterwards.
This is what ended up working for me. It is far from elegant but it works:
HSSFCellStyle intStyle = book.createCellStyle();
intStyle.setDataFormat((short)1);
HSSFCellStyle decStyle = book.createCellStyle();
decStyle.setDataFormat((short)2);
HSSFCellStyle dollarStyle = book.createCellStyle();
dollarStyle.setDataFormat((short)5);
for(int rowInd = 1; rowInd < rowCount; rowInd++) {
HSSFRow row = sheet.getRow(rowInd);
for(int cellInd = 1; cellInd < colCount; cellInd++) {
HSSFCell cell = row.getCell(cellInd);
//This is sortof a hack to counter PF exporting all data as text
//We capture the existing value as string, convert to int,
//then format the cell to be numeric and reset the value to be int
String strVal = cell.getStringCellValue();
//this has to be done to temporarily blank out the cell value
//because setting the type to numeric directly will cause
//an IllegalStateException because POI stupidly thinks
//the cell is text because it was exported as such by PF...
cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
strVal = strVal.replace(",", StringUtils.EMPTY);
if(strVal.indexOf('.') == -1) {
//integer
//numStyle.setDataFormat((short)1);
int intVal = Integer.valueOf(strVal);
cell.setCellStyle(intStyle);
cell.setCellValue(intVal);
} else {
//double
if(strVal.startsWith("$")) {
strVal = strVal.replace("$", StringUtils.EMPTY);
//numStyle.setDataFormat((short)5);
cell.setCellStyle(dollarStyle);
} else {
//numStyle.setDataFormat((short)2);
cell.setCellStyle(decStyle);
}
double dblVal = Double.valueOf(strVal);
cell.setCellValue(dblVal);
}
}
}
In your postProcessor, you nowhere set the value of the cell to an integer. You set the type, but not the value. Setting the type is not enough. You have to convert value to a number and set it again

Resources