简体   繁体   English

使用 Apache POI 刷新数据透视表

[英]Refresh Pivot table using Apache POI

No/Minimal documentation regarding Apache POI for Pivot tables in the Apache site has got me to write this.没有/关于 Apache 站点中数据透视表的 Apache POI 的最少文档让我写了这个。

I want to refresh a pivot table in a Work Book using Apache POI.我想使用 Apache POI 刷新工作簿中的数据透视表。

Please let me know where I can get proper documentation and Examples regarding this.请让我知道我可以在哪里获得有关此的适当文档和示例。

Kindly follow the followings which i did.请按照我所做的以下操作。

  1. Fill rough data for pivot table in your MyFileName.xlsx file.在 MyFileName.xlsx 文件中填充数据透视表的粗略数据。
  2. Create a Dynamic Range Formula through OFFSET() or Named Table as Source Data for Pivot table and draw pivot table.通过OFFSET()Named Table创建动态范围公式作为数据透视表的源数据并绘制数据透视表。
  3. Simply Right click your pivot table and choose只需右键单击您的数据透视表并选择

    pivotTable Options->Data-> Check Refresh Data when opening File

  4. Open a MyFileName.xlsx file and fill out the data.打开MyFileName.xlsx文件并填写数据。

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.注意:当您通过 POI 创建数据透视表时,这将不起作用。

The link codeMan refers to has some advice that looks quite specific to Apache POI & Excel. codeMan 所指的链接有一些看起来非常特定于 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你会看到这里没有很好的文档(不支持): http : //poi.apache.org/spreadsheet/limitations.html

To quote Solitudes answer in codeMans link verbatim:在 codeMans 链接中逐字引用 Solitudes 答案:

It is possible.有可能的。 In the PivotCacheDefinition, there is an attribute refreshOnLoad that can be set to true.在 PivotCacheDefinition 中,有一个属性 refreshOnLoad 可以设置为 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 > 在 POI 中,这可以通过调用方法 setRefreshOnLoad(boolean bool) 来完成,该方法将布尔值作为参数,在 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.如果您需要在打开文件之前刷新数据透视表,(例如,然后在进一步计算中使用数据透视表计算出的数据并让 POI 编写此内容),那么我不确定这对于 POI 是否可行,并且使用 COM 解决方案可能连接到 excel 可能是要走的路。

Apart from the limitations , you can check a little information about Package org.apache.poi.hssf.record.pivottable除了限制之外,您还可以查看有关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虽然如果我必须这样做,我会手动创建表格/图表一次,并将使用 apache poi 更新图表,就像我在这里所做的那样

save your file with PTs as file.将带有 PT 的文件另存为文件。 xlsm and insert VBA script (ALT+F11): xlsm并插入 VBA 脚本 (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缺点:客户端 xlsApp 应配置为启用 VBA 脚本

another solution (WO VBA scripts)另一种解决方案(WO VBA 脚本)

In tempalate.xlsx create xlTable object on headers of source record set.tempalate.xlsx 中,在源记录集的标题上创建 xlTable 对象。 Set name to the xlTable, ex.将名称设置为 xlTable,例如。 'mySourceTable'. '我的源表'。 Also in file preSet for your PivotTable:同样在数据透视表的文件预设中:

  1. sourceRef ='mySourceTable' sourceRef ='mySourceTable'
  2. check in RefreshOnLoad签入 RefreshOnLoad

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.注意:检查您的tempalate.xlsx是否有未知查询。 Delete if it exists, else it will block PT updating如果存在则删除,否则将阻止 PT 更新

Drawback: PT's autoFilter contains notexisting elements (elements from PT template).缺点:PT 的自动过滤器包含不存在的元素(来自 PT 模板的元素)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM