I'm currently working on a Java application that uses a template excel file that contains a pivot table.
The template file also has a data sheet that seeds the pivot table. This data sheet is dynamically loaded in the java application through the Apache POI api.
When I open the excel file I must refresh the Pivot table manually to get the data loaded correctly.
Is there any way to refresh the Pivot table with the POI api so I don't have to manually do it?
You can simple activate an option that will refresh the pivot table every time the file is opened.
This Microsoft documentation says :
In the PivotTable Options dialog box, on the Data tab, select the Refresh data when opening the file check box.
It is possible.
In the PivotCacheDefinition, there is an attribute refreshOnLoad that can be set to true. The cache is then refreshed when the workbook is opened. More information here.
In POI this can be done by calling the method setRefreshOnLoad(boolean bool), that takes a boolean as parameter, on a CTPivotCacheDefinition.
EDIT:
The Apache POI now provides the possibility to create pivot tables and the pivot table is refreshed on load as default. Class XSSFPivotTable
This post says you can turn on an option on the pivot table that will cause it to refresh itself automatically every time the workbook is opened:
How can I refresh all the pivot tables in my excel workbook with a macro?
Hopefully this will still be true after you have used Apache POI to refresh or extend the data rows on which the pivot tables are based.
protected void setRefreshPtOnLoad(boolean refreshOnLoad){
List<POIXMLDocumentPart.RelationPart> relationParts = ((XSSFWorkbook) workbook).getRelationParts();
for (POIXMLDocumentPart.RelationPart part : relationParts) {
PackageRelationship relationship = part.getRelationship();
if (relationship.getRelationshipType().contains("pivotCacheDefinition")){
String relationId = relationship.getId();
XSSFPivotCacheDefinition cache = (XSSFPivotCacheDefinition)((XSSFWorkbook) workbook).getRelationById(relationId);
CTPivotCacheDefinition ctCache = cache.getCTPivotCacheDefinition();
ctCache.setRefreshOnLoad(refreshOnLoad);
break; // if only pivot table cache exists in workbook, else - remove *break*
}
}
}
The basic answer to this is no. POI is a document format reader and writer. Updating the Pivot table is an excel engine issue. Sure, another application could try to duplicate the Excel engine behavior here, but that is really going to get ugly. I recommend using Joel's workaround of accessing the excel COM objects over a webservice to get this kind of thing done.
This might work:
XSSFPivotTable pivotTable = pivotSheet.getPivotTables().get(0);
pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().setRefreshOnLoad(true);
Related
I would like to provide a way for a sheet name to be specified by a command. The sheet names should be dynamically created based on the content in the sheet.
I note that it is possible to specify fixed sheet names for dynamic sheets when using the multisheet attribute of each-command.
In the version 1 documentation there is a reference to the ability to rename a sheet using ${workbook.setSheetName(0, department.name)}. Can this be used in v2? How is it supposed to work? Would workbook need to be added to the context or was it previously available?
I tried renaming the sheet in a custom command but it seems that there is too much dependence on sheet names in XlsArea for the name to be changed halfway through XlsArea.applyAt. The template sheet is not deleted and processing is not completed.
I thought about trying to get the custom command to add an area listener to change the sheet name. But the area listeners are only called on the parent area which I cannot access from within the command.
Thanks,
Wayne.
I doubt this is the correct way to do it, but til now this is the only way I've managed to do it:
Context context = PoiTransformer.createInitialContext();
Workbook workbook = WorkbookFactory.create(templateInputStream);
workbook.setSheetName(0, "newName");//Changing name of the first sheet
PoiTransformer transformer = PoiTransformer.createTransformer(workbook);
transformer.setOutputStream(resultOutputstream);
JxlsHelper.getInstance().processTemplate(context, transformer);
If you use multisheet generation feature you can just pass your own CellRefGenerator to Each-Command and create the sheet names dynamically in it.
Currently it is not possible to pass the CellRefGenerator in Excel template but it should be quite straightforward to add this functionality.
Or you can set the CellRefGenerator with Java code as shown in the documentation.
It can be done using folowing method of XLSTransformer class.
XLSTransformer transformer = new XLSTransformer();
setSpreadsheetToRename(oladSheetName, String newSheetName)
I am using Apache POI to generate xlsx sheet for reports. One of the POI generated report I saved as another using Microsoft excel . When comparing the original file and the saved file there was 12Mb difference. The original file was 15Mb while the saved file is just 2.5Mb. The Workbook used is XSSFWorkbook.
Is it possible to reduce the file size created by Apache POI
Here is the code snippet I have used:
XSSFWorkbook workbookTitle = new XSSFWorkbook(fileInputStream);
workbook = new SXSSFWorkbook(workbookTitle, maxRows);
font = workbook.createFont();
font.setFontHeightInPoints((short) 9);
font.setFontName(FONT_NAME);
cellTwoDecimal = workbook.createCellStyle();
DataFormat format = workbook.createDataFormat();
cellTwoDecimal.setDataFormat(format.getFormat("0.00"));
cellTwoDecimal.setFont(font);
cellCommon = workbook.createCellStyle();
cellCommon.setFont(font);
cellText = workbook.createCellStyle();
cellText.setDataFormat((short) BuiltinFormats.getBuiltinFormat("text"));
cellText.setFont(font);
cellWrpText = workbook.createCellStyle();
cellWrpText.setWrapText(true);
cellWrpText.setFont(font);
Row row;
Cell cell;
for (int i = 0; i < size; i++) {
row = excelSheet.createRow(rowIndex++);
cell = row.createCell(i);
cell.setCellValue(rowHeader);
cell.setCellStyle(cellCommon);
}
I have removed some internal logics from code. Please share your ideas.
[Edit 1]
I am inserting a lot of blank cells where there is no value, ie. some part of the report will not have any value. So I put a blank cell there. I am also setting style for the blank cell. Can this be the reason?
Thanks in advance.
According to your "edit 1"... if i understand you correctly you create cells with no value.
you do not have to do so. if you dont want to write something then do not create the empty cell.
on my poi-experience you only have to create rows and cells if you want to write something.
from this point of view it is clear, that your xlsx is very large (many many cell-objects). i think MS Excel removes the empty cells on manual save.
added: Need to mention that there is also an issue with styling your cells. please try to use as few as possible instances of CellStyle. if you have cells with same style do not create a new instance of CellStyle with same attributes. please apply the same instance of CellStyle. Also do not assign style to simple text cells. in this case excel uses a default style (background='white', textcolor='black', font='any default', size='any default', format='default').
I had a similar problem, and later figured out that I was opening the FileOutputStream in append mode(append=true). The file size grew exponentially(say from 7KB to 54KB) every-time I update a single cell on the sheet.
When removed the append, it worked just fine.
I am populating URL into Excel sheet through java code. But the hyperlink is not enabled if I populate through Java code.
If I type URL into Excel sheet directly, hyperlink automatically coming. Could you please let me know why it is not coming if I populate through code.
You may need Worksheet_followhyperlink enabled in the spreadsheet through vba. I've encountered this populating hyperlinks into Excel before. Pop this into the sheet with the links:
Private Sub Worksheet_followhyperlink(ByVal Target As Hyperlink)
Application.EnableEvents = True
Target.Follow
' Any other code you might need.
End Sub
I am using Apache POI to generate Exccel Templete which my clients could download, add values and upload back.
I would like to set the cell values non editable so that the template headers could not be edited.
I tried this code but it does not work,
cell.getCellStyle().setLocked(true)
I also read that locking the excel sheet and then allowing the columns to setlocked(false) would work but I am not sure how many columns will be filled by client, so I want is all other columns t be edited except the one which I filled dynamically with Apache POI.
I hope my query is clear to understand.
Try the following code, it may solve your problem:
HSSFWorkbook workbook = new XSSFWorkbook();
// Cell styles. Note the setLocked(true) method call.
HSSFCellStyle lockedNumericStyle = workbook.createCellStyle();
lockedNumericStyle.setAlignment(XSSFCellStyle.ALIGN_RIGHT);
lockedNumericStyle.setLocked(true);
HSSFSheet sheet = workbook.createSheet("Protection Test");
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell(0);
cell.setCellValue(100);
cell.setCellStyle(lockedNumericStyle);
// This line should cause all locked cells to be protected,
// the user should not be able to change the cells
// contents.
sheet.protectSheet("password");
The password makes it possible to remove the protection from the sheet and makes it possible then for the locked cells to be modified.
I don't recall how well this works -- for example, I think that the client can unprotect the sheet using the menu -- but you do need to protect the sheet via something like Sheet.protectSheet("") (no password, but nevertheless a protected sheet.)
I have a word document with checkboxes in it, and I want to determine whether these are ticked or not and use these results with java. I have tried using a WordExtractor with Apache POI but it didn't seem to include the result.
If I save the docx in txt format it replaces each checkbox with a corresponding 0 or 1, which is ideal, but I don't know how to do that programmatically.
Seems that you are looking for FtCblsSubRecord class (I didn't try it):
http://poi.apache.org/apidocs/org/apache/poi/hssf/record/FtCblsSubRecord.html
http://poi.apache.org/apidocs/org/apache/poi/hssf/record/class-use/SubRecord.html
Results of search in google: checkbox site:poi.apache.org
=========================================
By this post seems not to be posible:
http://osdir.com/ml/user-poi.apache.org/2010-10/msg00068.html
Other post talking about this:
What API can add checkbox to MS Word file using Java?
Insert a checkbox in an Excel sheet using Apache POI