Apache POI: changing CellType causes IllegalStateException - java

Why is it illegal to change cell type in Apache POI? The code bellow causes IllegalStateException: Cannot get a error value from a numeric cell.
Cell mycell = myrow.createCell(0);
// Make it numeric by default.
mycell.setCellType(Cell.CELL_TYPE_NUMERIC);
if (someCondition) {
mycell.setCellType(Cell.CELL_TYPE_STRING); // IllegalStateException
}
Is there perhaps a way around this problem (as in without introducing additional logic)?

Im not sure this is avoiding your "without additional logic" but here goes:
Cell mycell = myrow.createCell(0);
// Make it numeric by default.
int cellType = Cell.CELL_TYPE_NUMERIC;
if (someCondition) {
cellType = Cell.CELL_TYPE_STRING;
}
mycell.setCellType(cellType);
The Javadoc does not state why it would throw an IllegalStateException so I would just avoid it (by doing the above) or go digging in the sourcecode.

Fixed it. After replacing the streaming version (org.apache.poi.xssf.streaming.SXSSFWorkbook) with the non-streaming one (org.apache.poi.xssf.usermodel.XSSFWorkbook) the exception was gone. I'm okay with XSSFWorkbook since I'm filling XLSX with only a couple of lines.

Related

iText 5.5.11 - bold text looks blurry after using PdfCleanUpProcessor

I need to remove some content from an existing pdf created with Jasper Reports in iText 5.5.11 but after running PdfCleanUpProcessor all bold text is blurry.
This is the code I'm using:
PdfReader reader = new PdfReader("input.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("output.pdf"));
List<PdfCleanUpLocation> cleanUpLocations = new ArrayList<PdfCleanUpLocation>();
cleanUpLocations.add(new PdfCleanUpLocation(1, new Rectangle(0f, 0f, 595f, 680f)));
PdfCleanUpProcessor cleaner = new PdfCleanUpProcessor(cleanUpLocations, stamper);
cleaner.cleanUp();
stamper.close();
reader.close();
As already discussed here downgrading to itext-5.5.4 solves the problem, but in my case itext-5.5.11 is already in use for other reasons and so downgrading is not an option.
Is there another solution or workaround?
This are the pdf files before and after cleaning: BEFORE - AFTER
By comparing the before and after files it becomes clear that for some reason the PdfCleanUpProcessor falsely drops general graphics state operations (at least w, J, and d).
In your before document in particular the w operation is important for the text because a poor man's bold variant is used, i.e. instead of using an actual bold font the normal font is used and the text rendering mode is set to not only fill the glyph contours but also draw a line along it giving it a bold'ish appearance.
The width of that line is set to 0.23333 using a w operation. As that operation is missing in the after document, the default width value of 1 is used. Thus, the line along the contour now is 4 times as big as before resulting in a very fat appearance.
This issue has been introduced in commit d5abd23 (dated May 4th, 2015) which (among other things) added this block to PdfCleanUpContentOperator.invoke:
} else if (lineStyleOperators.contains(operatorStr)) {
if ("w" == operatorStr) {
cleanUpStrategy.getContext().setLineWidth(((PdfNumber) operands.get(0)).floatValue());
} else if ("J" == operatorStr) {
cleanUpStrategy.getContext().setLineCapStyle(((PdfNumber) operands.get(0)).intValue());
} else if ("j" == operatorStr) {
cleanUpStrategy.getContext().setLineJoinStyle(((PdfNumber) operands.get(0)).intValue());
} else if ("M" == operatorStr) {
cleanUpStrategy.getContext().setMiterLimit(((PdfNumber) operands.get(0)).floatValue());
} else if ("d" == operatorStr) {
cleanUpStrategy.getContext().setLineDashPattern(new LineDashPattern(((PdfArray) operands.get(0)),
((PdfNumber) operands.get(1)).floatValue()));
}
disableOutput = true;
This causes all lineStyleOperators to be dropped while at the same time an attempt was made to store the changed values in the cleanup strategy context. But of course using == for String comparisons in Java usually is a very bad idea, so since this version the line style operators were dropped for good in iText.
Actually this code had been ported from iTextSharp, and in C# == for the string type works entirely different; nonetheless, even in the iTextSharp version these stored values at first glance only seem to have been taken into account if paths were stroked, not if text rendering included stroking along the contour.
Later on in commit 9967627 (on the same day as the commit above) the inner if..else if..else.. has been removed with the comment Replaced PdfCleanUpGraphicsState with existing GraphicsState from itext.pdf.parser package, added missing parameters into the latter, only the disableOutput = true remained. This (also at first glance) appears to have fixed the difference between iText/Java and iTextSharp/.Net, but the line style values still are not considered if text rendering included stroking along the contour.
As a work-around consider removing the lines
} else if (lineStyleOperators.contains(operatorStr)) {
disableOutput = true;
from PdfCleanUpContentOperator.invoke. Now the line style operators are not dropped anymore and the text in your PDF after redaction looks like before. I have not checked for any side effects, though, so please test with a number of documents before even considering using that work-around in production.

iText Barcode128 - illegal characters for barcode

I'm attempting to generate a barcode128 in iText, with the following code:
Barcode128 shipBarCode = new Barcode128();
shipBarCode.setCode(getOrder().getPartnerPurchaseOrderNumber());
shipBarCode.setBarHeight(40f);
PdfPCell barCodeCell = new PdfPCell();
barCodeCell.addElement(
shipBarCode.createImageWithBarcode(cb, BaseColor.BLACK, BaseColor.BLACK)
);
barCodeCell.setFixedHeight(55f);
barCodeCell.setPaddingRight(15f);
barCodeCell.setBorder(Rectangle.NO_BORDER);
barCodeCell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(barCodeCell);
but I'm receiving the following exception:
java.lang.RuntimeException: There are illegal characters for barcode 128 in '509868_1_2_1'.
at com.itextpdf.text.pdf.Barcode128.getRawText(Barcode128.java:518)
at com.stuhrling.orderprocessing.partner.shopnbc.ShopNBCPackingSlip.getOrderInfoTable(ShopNBCPackingSlip.java:142)
at com.stuhrling.orderprocessing.partner.shopnbc.ShopNBCPackingSlip.getPackingSlipElement(ShopNBCPackingSlip.java:610)
at com.stuhrling.orderprocessing.label.PDFComboLabel.packingSlipCell(PDFComboLabel.java:131)
at com.stuhrling.orderprocessing.label.PDFComboLabel.generateLabel(PDFComboLabel.java:87)
at com.stuhrling.orderprocessing.OrderService.generatePackingSlip(OrderService.java:731)
at com.stuhrling.orderprocessing.PackingSlipListener.handleMessage(PackingSlipListener.java:60)
at com.stuhrling.orderprocessing.messaging.MessageListener.run(MessageListener.java:76)
at java.lang.Thread.run(Thread.java:745)
Apparently, code 128 does not read underscores.. or maybe it's a bug in iText?
Does anyone know of a workaround for this in iText?
Update:
Looks like it bugs out even without the underscore, so now I'm even more stumped... :(
I wonder what's wrong with my code?
BTW, It only happens if I have only numbers; if I add a letter the problem disappears.
I don't know if I'm right about this, but I thought it might be a bug. After stepping through itext's Barcode128.java I changed this (line 442):
if (currentCode != codeSet.getStartSymbol())
throw new RuntimeException(MessageLocalization.getComposedMessage("there.are.illegal.characters.for.barcode.128.in.1", text));
to this:
if (codeSet != Barcode128CodeSet.AUTO && currentCode != codeSet.getStartSymbol())
throw new RuntimeException(MessageLocalization.getComposedMessage("there.are.illegal.characters.for.barcode.128.in.1", text));
The itext version is 5.5.4. If there is anyone out there familiar with the code, perhaps you can tell me whether this truly is a bug.
I think itextpdf 5.5.4 bug.
When I upgraded to 5.5.12, it is resolved.

POI Excel Merging Causing "Repaired Records: Format from /xl/styles.xml part (Styles)"

I have merged two excel files using the code specied here
http://www.coderanch.com/t/614715/Web-Services/java/merge-excel-files
this the block applying the styles for my merging cells
if (styleMap != null)
{
if (oldCell.getSheet().getWorkbook() == newCell.getSheet().getWorkbook())
{
newCell.setCellStyle(oldCell.getCellStyle());
}
else
{
int stHashCode = oldCell.getCellStyle().hashCode();
XSSFCellStyle newCellStyle = styleMap.get(stHashCode);
if (newCellStyle == null)
{
newCellStyle = newCell.getSheet().getWorkbook().createCellStyle();
newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
styleMap.put(stHashCode, newCellStyle);
}
newCell.setCellStyle(newCellStyle);
}
}
It all working as expected and going well in generating my XSSFWorkbook.
Problem starting when I try to open it:
I see below error
and my error report contains below
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<logFileName>error072840_01.xml</logFileName>
<summary>Errors were detected in file 'XYZ.xlsx'</summary>
<repairedRecords summary="Following is a list of repairs:">
<repairedRecord>Repaired Records: Format from /xl/styles.xml part (Styles)</repairedRecord>
</repairedRecords>
</recoveryLog>
After all these my sheet opens up fine but without styles. I know there is a limitation on number of styles to be created and have counted the styles being created and I hardly see 4 created. I even know that this issue is with too many styles.
Unfortunately, POI has support to optimise only HSSFWorkbook (Apache POI delete CellStyle from workbook)
Any help in how to mitigate with this issue will be great.
Well, after debugging bit of POI code and how styles are being applied and so.
Doing below solved the problem
newCellStyle.getCoreXf().unsetBorderId();
newCellStyle.getCoreXf().unsetFillId();
I had the same issue.
You should to minimize instances of styles and fonts because each instance is placed into xl/styles.xml
Make styles and fonts only once for one book.
I had the same issue using the Python library xlxswriter with Pandas. After I stopped trying to use Pandas' date_format specification, I stopped getting the error.
import pandas as pd
data = pd.read_excel('somefile.xlsx')
grp = data.groupby('Property Manager')
for i, (pm, g) in enumerate(grp):
writer = pd.ExcelWriter(p + f.format(pm[:30]), engine='xlsxwriter') #,date_format='%m/%d/%Y')
g[cols].to_excel(writer, sheet_name='Summary', index=False)
writer.save()

Predicate implementation inquiry FilreredRowSet in JAVA

I have the following predicate implementation:
public boolean evaluate(RowSet rowset )
{try{
int count=0;
CachedRowSet crs = (CachedRowSet)rowset;
{
if (!crs.isAfterLast())//CRUCIAL LINE
for (int i=0;i<index.length;i++)
{
if ((crs.getObject(index[i])).toString().compareTo(high[i].toString())<=0)
{
if ((crs.getObject(index[i])).toString().compareTo(low[i].toString())>=0)
{
count++;
}
}
}
}
Now, if I comment out the "crucial line" hence:
if (!crs.isAfterLast())
I will get a java.sql.SQLException: Invalid cursor position.
Why does it happen so? Does not it get used the .next() method returning false if the next line is afterLast?
I can traverse any resultset without having to check if (!crs.isAfterLast()). Just using rs.next() would be enough as it returns false if next is after the last.
Why in predicate this does not happen? Thanks in advance.
The issue you are encountering is a bug in Java 7 (even in 7.0_45), documented here: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7166598
A simple workaround to avoid the "Invalid cursor position" SQLException that worked for me is to add this logic to the start of your implementation of Predicate.evaluate(RowSet rs) to detect the end-of-rowset condition:
FilteredRowSet frs = (FilteredRowSet) rs;
int rowNum = frs.getRow();
if (rowNum == 0) { // Meaning "no current row" - should never happen...
return false; // Needed only to address a bug in Java 7
}
Your workaround of calling isAfterLast() also seems fine, and the ugly workaround of simply swallowing the SQLException also works, since the exception occurs after all processing is complete.
The problem is fixed under Java 8 RTE, and recompilation is not necessary.
I have specifically tested a Predicate implementation which is failing under Java 7 using Java 8, within Intellij Idea, and also from the command line. Under Java 8 it also works fine without needing the Java 7 workaround described above.

Eclipse shows error for MissingCellPolicy

I am using Apache POI to read data from Excel files. I have some blank/null cells in my Excel which I want to handle using MissingCellPolicy.RETURN_NULL_AND_BLANK. However, Eclipse underlines RETURN_NULL_AND_BLANK when I hover the mouse over it and I get a pop-up saying RETURN_NULL_AND_BLANK cannot be resolved or is not a field
I have imported the Row.MissingCellPolicy class. Can anyone point out what needs to be done?
MissingCellPolicy is the static nested class of the Row interface. And RETURN_NULL_AND_BLANK is the static field of the ROW interface.
So you should access with:
Row.RETURN_NULL_AND_BLANK;
Or use static import instead:
import static org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
import static org.apache.poi.ss.usermodel.Row.RETURN_NULL_AND_BLANK;
//....
MissingCellPolicy policy = RETURN_NULL_AND_BLANK;
Adding Row.RETURN_NULL_AND_BLANK; helped me instead of adding Row.MissingCellPolicy.RETURN_NULL_AND_BLANK; or MissingCellPolicy.RETURN_NULL_AND_BLANK; and Eclipse doesn't throw error.
This is because my worksheet is XSSFSheet which returns an XSSFRow just Row and XSSFRow (or even HSSFRow for that matter) directly inherits these constants from the Row class. See more info here
Row is interface
MissingCellPolicy is the enum in Row
and
1. RETURN_NULL_AND_BLANK
2. RETURN_BLANK_AS_NULL
3. CREATE_NULL_AS_BLANK
is the static field
To Access any of 1 to 3
use
Row.MissingCellPolicy.RETURN_NULL_AND_BLANK
or use other two as per requirement

Categories