使用Apache POI刷新数据透视表

13

缺乏关于 Apache 网站中 Apache POI 透视表方面的文档,因此我需要写这篇文章。

我想使用 Apache POI 刷新工作簿中的透视表。

请告诉我在哪里可以获得有关此方面的适当文档和示例。


1
您可以参考类似的以下问题的答案 - https://dev59.com/K3NA5IYBdhLWcg3wUMHn - codeMan
3
以上问题的答案与Apache poi无关。 - pavi
Apache POI 在这里无法发挥太大作用。详细情况和解决方法请参见 http://www.joelonsoftware.com/items/2008/02/19.html。 - Jayan
5个回答

3
请按照以下步骤操作:
  1. 在MyFileName.xlsx文件中填写数据,并为数据透视表填写粗略数据。
  2. 通过OFFSET()命名表创建动态范围公式作为数据透视表的源数据,然后绘制数据透视表。
  3. 右键单击您的数据透视表,选择

    数据透视表选项->数据->打开文件时检查刷新数据

  4. 打开MyFileName.xlsx文件并填写数据。

这样,每次打开工作簿时,它都会刷新到当前数据。请注意:如果使用POI创建数据透视表,则此方法不起作用。

1

1
链接codeMan所提到的内容包含一些关于Apache POI和Excel的具体建议。你会发现,这里没有很好的文档(它不受支持): http://poi.apache.org/spreadsheet/limitations.html 引用Solitudes在codeMans链接中的答案:
"这是可能的。在PivotCacheDefinition中,有一个属性refreshOnLoad,可以设置为true。然后在打开工作簿时刷新缓存。更多信息请参见此处。 > 在POI中,可以通过在CTPivotCacheDefinition上调用带有布尔参数的方法setRefreshOnLoad(boolean bool)来实现这一点。"
如果您需要在打开文件之前刷新数据透视表(例如,使用数据透视表计算数据进行进一步计算,并让POI写入此数据),则我不确定是否可能使用POI完成此操作。可能使用COM解决方案连接Excel可能是解决问题的方法。

0

将文件保存为PTs格式,文件名为.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

缺点:客户端的xlsApp应该配置以启用VBA脚本。

0

另一种解决方案(无需 VBA 脚本)

tempalate.xlsx 中,在源记录集的标题上创建 xlTable 对象。将名称设置为 xlTable,例如 'mySourceTable'。 还要在文件 preSet 中为您的数据透视表进行预设:

  1. sourceRef ='mySourceTable'
  2. 检查 RefreshOnLoad

在 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);
    }

注意:检查您的tempalate.xlsx是否存在未知查询。如果存在,请删除,否则将阻止 PT 更新。

缺点:PT 的自动筛选器包含不存在的元素(来自 PT 模板)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接