No/Minimal documentation regarding Apache POI for Pivot tables in the Apache site has got me to write this.
I want to refresh a pivot table in a Work Book using Apache POI.
Please let me know where I can get proper documentation and Examples regarding this.
Kindly follow the followings which i did.
OFFSET()
or Named Table
as Source Data for Pivot table and draw pivot table.Simply Right click your pivot table and choose
pivotTable Options->Data-> Check Refresh Data when opening File
Open a MyFileName.xlsx
file and fill out the data.
That's all... whenever you opening workbook it will be refreshed to current data. :-)
Note: This will not work when you creating Pivot table through POI.
The link codeMan refers to has some advice that looks quite specific to Apache POI & Excel. You'll see that there is no great documentation for a reason here (it's not supported): http://poi.apache.org/spreadsheet/limitations.html
To quote Solitudes answer in codeMans link verbatim:
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
If you need to refresh the pivot table before the file is opened, (for example to then use the pivottable calculated data in further calculations and have POI write this) then I'm not sure that this would be possible at all with POI, and potentially hooking up to excel using a COM solution might be the way to go.
Apart from the limitations , you can check a little information about Package org.apache.poi.hssf.record.pivottable
Though if I will have to do the same, I would create the table/chart manually once and will update the chart using apache poi as I have done here
save your file with PTs as file. xlsm and insert VBA script (ALT+F11):
' Create module and insert this:
Public Const pivotName1 As String = "myPivotName"
Public Const sourceSheetName As String = "source"
Public Const sourceColumnCount As Long = 23
' In "ThisWorkbook" chapter insert this:
Dim lRow As Long
Private Sub Workbook_Open()
Application.ScreenUpdating = False
ActiveWorkbook.Worksheets(sourceSheetName).Activate
' In file should preliminarily insert keyWord "firstOpenFlag" in CV1 cell (sheet sourceSheetName)
' It gona start actions below
If ActiveSheet.Cells(1, 100) = "firstOpenFlag"
Then
ActiveSheet.Cells(1, 100) = ""
lRow = getLastRowForFirstCol(sourceSheetName)
Call updateAllPTCache
ActiveWorkbook.Worksheets(sourceSheetName).Activate
ActiveSheet.Range("A1").Select
End If
Application.ScreenUpdating = True
End Sub
Private Function getLastRowForFirstCol(sourceSheetName As String) As Long
ActiveWorkbook.Worksheets(sourceSheetName).Activate
getLastRowForFirstCol = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
If getLastRowForFirstCol < 2 Then getLastRowForFirstCol = 2
End Function
Private Sub updateAllPTCache()
Dim pt As PivotTable
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
For Each pt In ws.PivotTables
pt.ChangePivotCache ActiveWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, _
SourceData:=sourceSheetName + "!R1C1:R" + CStr(lRow) + "C" + CStr(sourceColumnCount), _
Version:=xlPivotTableVersion14)
' xlPivotTableVersion14 - work in 2013, 2016 exlApp
' Downgrade xlPivotTableVersion for backward compatibility
pt.RefreshTable
Next pt
Next ws
End Sub
Drawback: clients xlsApp should be configed to enable VBA scripts
another solution (WO VBA scripts)
In tempalate.xlsx create xlTable object on headers of source record set. Set name to the xlTable, ex. 'mySourceTable'. Also in file preSet for your PivotTable:
In POI:
private void updateXlTableSource() {
XSSFTable sourceTable = ((XSSFWorkbook)workbook).getTable("mySourceTable");
CTTable ctTable = sourceTable.getCTTable();
String sourceRef = getSourceDataRange().formatAsString();
ctTable.setRef(sourceRef);
ctTable.getAutoFilter().setRef(sourceRef);
}
private CellRangeAddress getSourceDataRange() {
XSSFSheet xssfSheet = (XSSFSheet) workbook.getSheet("sourceSheetName");
int uBoundSourceDataRow = findFirstEmptyRowFrom(xssfSheet) - 1;
if (uBoundSourceDataRow < 2) {
uBoundSourceDataRow = 2;
}
int uBoundSourceDataCol = findFirstEmptyColFromFirstRow(xssfSheet) - 1;
return new CellRangeAddress(0, uBoundSourceDataRow, 0, uBoundSourceDataCol);
}
Note: check your tempalate.xlsx for unKnown query. Delete if it exists, else it will block PT updating
Drawback: PT's autoFilter contains notexisting elements (elements from PT template).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.