Uppdatera pivottabeller och pivotcacheminnen i Aspose.Cells for C++

Introduktion

Att uppdatera en pivottabell är sällan en enstaka åtgärd. Bakom kulisserna underhåller Aspose.Cells en skiktad datakedja som kopplar samman dina ursprungliga källdata med de renderade värden du ser i kalkylbladet. Att förstå denna kedja är nyckeln till att välja rätt uppdaterings-API för varje situation. Den fyra-skikts datakedjan är:

  1. Datakälla — de ursprungliga kalkylbladsintervallen, databasfrågan eller konsolideringsintervallet där råvärdena finns.
  2. PivotCache — den minnesinterna ögonblicksbilden av källdatan. Varje pivottabell är byggd ovanpå en PivotCache; det är här all data samlas in och aggregeras.
  3. PivotTable — vyobjektet som definierar rad-, kolumn-, värde- och filterfält. En PivotTable läser bara från sin PivotCache, aldrig direkt från datakällan.
  4. Cells — kalkylbladets Cells som PivotTable renderar sina beräknade värden och stilar till.

På grund av denna kedja finns det två grundläggande uppdateringsvägar i Aspose.Cells:

  • PivotTable.CalculateData() — beräknar om en PivotTables visning från redan cachad data, utan returresa till datakällan. Alla scenarier i den här artikeln använder kalkylblads-celler som källdata, så källtypen är Sheet och uppdateringsåtgärderna fungerar enligt beskrivningen.

Snabbstart

Om du bara behöver den kortaste möjliga koden som uppdaterar varje pivot i arbetsboken räcker ett enda anrop:

#include "Aspose.Cells.h"
using namespace Aspose::Cells;
using namespace Aspose::Cells::Pivot;
int main() {
    Aspose::Cells::Startup();
    Workbook wb;
    Worksheet worksheet = wb.GetWorksheets().Get(0);
    Cells cells = worksheet.GetCells();
    cells.Get(u"A1").PutValue(U16String("Fruit"));
    cells.Get(u"B1").PutValue(U16String("Year"));
    cells.Get(u"C1").PutValue(U16String("Amount"));
    cells.Get(u"A2").PutValue(U16String("grape"));
    cells.Get(u"B2").PutValue(2020);
    cells.Get(u"C2").PutValue(50);
    cells.Get(u"A3").PutValue(U16String("blueberry"));
    cells.Get(u"B3").PutValue(2020);
    cells.Get(u"C3").PutValue(60);
    cells.Get(u"A4").PutValue(U16String("kiwi"));
    cells.Get(u"B4").PutValue(2020);
    cells.Get(u"C4").PutValue(70);
    cells.Get(u"A5").PutValue(U16String("cherry"));
    cells.Get(u"B5").PutValue(2020);
    cells.Get(u"C5").PutValue(80);
    cells.Get(u"A6").PutValue(U16String("grape"));
    cells.Get(u"B6").PutValue(2021);
    cells.Get(u"C6").PutValue(90);
    cells.Get(u"A7").PutValue(U16String("blueberry"));
    cells.Get(u"B7").PutValue(2021);
    cells.Get(u"C7").PutValue(100);
    cells.Get(u"A8").PutValue(U16String("kiwi"));
    cells.Get(u"B8").PutValue(2021);
    cells.Get(u"C8").PutValue(110);
    cells.Get(u"A9").PutValue(U16String("cherry"));
    cells.Get(u"B9").PutValue(2021);
    cells.Get(u"C9").PutValue(120);
    int pivotIndex = worksheet.GetPivotTables().Add(u"A1:C9", u"E3", u"Pivot1");
    PivotTable pivotTable = worksheet.GetPivotTables().Get(pivotIndex);
    pivotTable.AddFieldToArea(PivotFieldType::Row, u"Fruit");
    pivotTable.AddFieldToArea(PivotFieldType::Column, u"Year");
    pivotTable.AddFieldToArea(PivotFieldType::Data, u"Amount");
    cells.Get(u"C2").PutValue(55);
    cells.Get(u"C5").PutValue(85);
    cells.Get(u"C9").PutValue(125);
    pivotTable.CalculateData();
    wb.Save(u"output.xlsx");
    Aspose::Cells::Cleanup();
    return 0;
}

Allt annat i den här artikeln förklarar när du bör välja ett smalare API istället.

Nödvändiga inkluderingsdirektiv

Alla C++-exempel i den här artikeln börjar med följande headerinkluderingar och namnrymdsdirektiv eftersom pivottyperna ligger i namnrymden Aspose::Cells::Pivot:

  • #include <system/object.h>
  • #include "Aspose.Cells.h"
  • using namespace Aspose::Cells;
  • using namespace Aspose::Cells::Pivot;

Uppdatera alla pivottabeller i arbetsboken

När du behöver säkerställa att varje pivotcache och varje pivottabell i arbetsboken återspeglar de senaste källdatan är det enklaste och mest heltäckande API:et Workbook.RefreshAll(). Ett enda anrop traverserar hela arbetsboken — uppdaterar varje PivotCache från sin källa och beräknar sedan om varje beroende PivotTable. Detta är det rekommenderade tillvägagångssättet för allmänna, heltäckande dokumentuppdateringar där prestanda inte är ett bekymmer. Följande exempel bygger en arbetsbok med ett källintervall för Fruit/Year/Amount, skapar en pivottabell, ändrar några källvärden och använder sedan RefreshAll() för att föra allt uppdaterat i ett enda anrop.

#include "Aspose.Cells.h"
using namespace Aspose::Cells;
int main() {
    Aspose::Cells::Startup();
    Workbook workbook;
    Worksheet worksheet = workbook.GetWorksheets().Get(0);
    worksheet.GetCells().Get(u"A1").PutValue(u"Fruit");
    worksheet.GetCells().Get(u"B1").PutValue(u"Year");
    worksheet.GetCells().Get(u"C1").PutValue(u"Amount");
    worksheet.GetCells().Get(u"A2").PutValue(u"grape");
    worksheet.GetCells().Get(u"B2").PutValue(2020);
    worksheet.GetCells().Get(u"C2").PutValue(100);
    worksheet.GetCells().Get(u"A3").PutValue(u"blueberry");
    worksheet.GetCells().Get(u"B3").PutValue(2021);
    worksheet.GetCells().Get(u"C3").PutValue(150);
    worksheet.GetCells().Get(u"A4").PutValue(u"kiwi");
    worksheet.GetCells().Get(u"B4").PutValue(2020);
    worksheet.GetCells().Get(u"C4").PutValue(200);
    worksheet.GetCells().Get(u"A5").PutValue(u"cherry");
    worksheet.GetCells().Get(u"B5").PutValue(2021);
    worksheet.GetCells().Get(u"C5").PutValue(120);
    worksheet.GetCells().Get(u"A6").PutValue(u"grape");
    worksheet.GetCells().Get(u"B6").PutValue(2021);
    worksheet.GetCells().Get(u"C6").PutValue(180);
    worksheet.GetCells().Get(u"A7").PutValue(u"blueberry");
    worksheet.GetCells().Get(u"B7").PutValue(2020);
    worksheet.GetCells().Get(u"C7").PutValue(130);
    worksheet.GetCells().Get(u"A8").PutValue(u"kiwi");
    worksheet.GetCells().Get(u"B8").PutValue(2021);
    worksheet.GetCells().Get(u"C8").PutValue(220);
    worksheet.GetCells().Get(u"A9").PutValue(u"cherry");
    worksheet.GetCells().Get(u"B9").PutValue(2020);
    worksheet.GetCells().Get(u"C9").PutValue(140);
    int pivotIndex = worksheet.GetPivotTables().Add(u"A1:C9", u"E3", u"Pivot1");
    PivotTable pivotTable = worksheet.GetPivotTables().Get(pivotIndex);
    pivotTable.AddFieldToArea(PivotFieldType::Row, u"Fruit");
    pivotTable.AddFieldToArea(PivotFieldType::Column, u"Year");
    pivotTable.AddFieldToArea(PivotFieldType::Data, u"Amount");
    worksheet.GetCells().Get(u"C2").PutValue(300);
    worksheet.GetCells().Get(u"C5").PutValue(250);
    worksheet.GetCells().Get(u"C9").PutValue(400);
    worksheet.RefreshPivotTables();
    workbook.Save(u"output.xlsx");
    Aspose::Cells::Cleanup();
    return 0;
}

Uppdatera alla pivottabeller på ett enskilt kalkylblad

Ibland behöver du bara uppdatera de pivottabeller som finns på ett specifikt kalkylblad — till exempel när pivottabeller på andra kalkylblad är kända för att vara orelaterade och inte bör röras. För detta fall tillhandahåller Aspose.Cells Worksheet.RefreshPivotTables(), som är begränsat till en enda Worksheet-instans.

#include "Aspose.Cells.h"
using namespace Aspose::Cells;
int main() {
    Aspose::Cells::Startup();
    Workbook workbook;
    Worksheet worksheet = workbook.GetWorksheets().Get(0);
    // Skriv rubrikrad för Frukt / År / Belopp
    worksheet.GetCells().Get(u"A1").PutValue(u"Fruit");
    worksheet.GetCells().Get(u"B1").PutValue(u"Year");
    worksheet.GetCells().Get(u"C1").PutValue(u"Amount");
    // Skriv 8 datarader (raderna 2–9, som passar källintervallet A1:C9)
    worksheet.GetCells().Get(u"A2").PutValue(u"Grape");
    worksheet.GetCells().Get(u"B2").PutValue(2020);
    worksheet.GetCells().Get(u"C2").PutValue(100);
    worksheet.GetCells().Get(u"A3").PutValue(u"Blueberry");
    worksheet.GetCells().Get(u"B3").PutValue(2020);
    worksheet.GetCells().Get(u"C3").PutValue(200);
    worksheet.GetCells().Get(u"A4").PutValue(u"Kiwi");
    worksheet.GetCells().Get(u"B4").PutValue(2020);
    worksheet.GetCells().Get(u"C4").PutValue(300);
    worksheet.GetCells().Get(u"A5").PutValue(u"Cherry");
    worksheet.GetCells().Get(u"B5").PutValue(2020);
    worksheet.GetCells().Get(u"C5").PutValue(400);
    worksheet.GetCells().Get(u"A6").PutValue(u"Grape");
    worksheet.GetCells().Get(u"B6").PutValue(2021);
    worksheet.GetCells().Get(u"C6").PutValue(150);
    worksheet.GetCells().Get(u"A7").PutValue(u"Blueberry");
    worksheet.GetCells().Get(u"B7").PutValue(2021);
    worksheet.GetCells().Get(u"C7").PutValue(250);
    worksheet.GetCells().Get(u"A8").PutValue(u"Kiwi");
    worksheet.GetCells().Get(u"B8").PutValue(2021);
    worksheet.GetCells().Get(u"C8").PutValue(350);
    worksheet.GetCells().Get(u"A9").PutValue(u"Cherry");
    worksheet.GetCells().Get(u"B9").PutValue(2021);
    worksheet.GetCells().Get(u"C9").PutValue(450);
    // Lägg till en pivottabell med namnet "Pivot1" placerad i målcellen E3, med källa från A1:C9
    int pivotIndex = worksheet.GetPivotTables().Add(u"A1:C9", u"E3", u"Pivot1");
    PivotTable pivotTable = worksheet.GetPivotTables().Get(pivotIndex);
    // Tilldela fält: Fruit till Rad, Year till Kolumn, Amount till Data
    pivotTable.AddFieldToArea(PivotFieldType::Row, u"Fruit");
    pivotTable.AddFieldToArea(PivotFieldType::Column, u"Year");
    pivotTable.AddFieldToArea(PivotFieldType::Data, u"Amount");
    // Ändra en egenskap för vy/layout — detta är en ändring som endast gäller presentation,
    // så den kräver INTE att källdatan läses igen via PivotCache.Refresh().
    pivotTable.SetRefreshDataOnOpeningFile(false);
    // CalculateData() renderar om DEN HÄ pivottabellens visning (data + stil) från
    // datan som redan finns i PivotCache. Eftersom källdatan inte ändrades
    // görs ingen tur-och-retur till källan — endast de cachelagrade värdena beräknas om
    // till kalkylbladsceller.
    pivotTable.CalculateData();
    // Spara arbetsboken till disk
    workbook.Save(u"output.xlsx");
    Aspose::Cells::Cleanup();
    return 0;
}

Uppdatera en enskild pivottabell

När du vill ha finkornig kontroll över en enskild pivottabell ger det cache-baserade API:et dig två alternativ. Valet mellan dem beror på vad som faktiskt har ändrats: underliggande källdata, eller bara vy-/layoutinställningarna för själva pivottabellen.

Källdata har ändrats — Använd PivotCache.Refresh()

Om underliggande källdata har ändrats är rätt startpunkt pivotTable.GetPivotCache().Refresh(). Detta anrop läser om källdatan till cacheminnet och beräknar sedan om varje PivotTable som är beroende av det cacheminnet.

Endast vy/layout har ändrats — Använd CalculateData()

Om källdatan inte har ändrats men bara pivottabellens vy- eller layoutinställningar har modifierats (till exempel att ett fält har flyttats till ett annat område, eller att en refresh-on-open-inställning har växlats), finns det inget behov av en returresa till datakällan. Cacheminnet innehåller redan rätt data; bara den renderade PivotTable behöver beräknas om. I detta fall är pivotTable.CalculateData() rätt val. Följande exempel modifierar en icke-käll-egenskap hos pivottabellen och anropar sedan CalculateData() för att rendera om den från befintligt cacheminne.

#include "Aspose.Cells.h"
using namespace Aspose::Cells;
using namespace Aspose::Cells::Pivot;
int main() {
    Aspose::Cells::Startup();
    Workbook wb;
    Worksheet sheet = wb.GetWorksheets().Get(0);
    sheet.GetCells().Get(u"A1").PutValue(u"Fruit");
    sheet.GetCells().Get(u"B1").PutValue(u"Year");
    sheet.GetCells().Get(u"C1").PutValue(u"Amount");
    sheet.GetCells().Get(u"A2").PutValue(u"Grape");      sheet.GetCells().Get(u"B2").PutValue(2020); sheet.GetCells().Get(u"C2").PutValue(1000);
    sheet.GetCells().Get(u"A3").PutValue(u"Blueberry");  sheet.GetCells().Get(u"B3").PutValue(2020); sheet.GetCells().Get(u"C3").PutValue(2000);
    sheet.GetCells().Get(u"A4").PutValue(u"Kiwi");       sheet.GetCells().Get(u"B4").PutValue(2020); sheet.GetCells().Get(u"C4").PutValue(1500);
    sheet.GetCells().Get(u"A5").PutValue(u"Cherry");     sheet.GetCells().Get(u"B5").PutValue(2020); sheet.GetCells().Get(u"C5").PutValue(2500);
    sheet.GetCells().Get(u"A6").PutValue(u"Grape");      sheet.GetCells().Get(u"B6").PutValue(2021); sheet.GetCells().Get(u"C6").PutValue(3000);
    sheet.GetCells().Get(u"A7").PutValue(u"Blueberry");  sheet.GetCells().Get(u"B7").PutValue(2021); sheet.GetCells().Get(u"C7").PutValue(1800);
    sheet.GetCells().Get(u"A8").PutValue(u"Kiwi");       sheet.GetCells().Get(u"B8").PutValue(2021); sheet.GetCells().Get(u"C8").PutValue(2200);
    sheet.GetCells().Get(u"A9").PutValue(u"Cherry");     sheet.GetCells().Get(u"B9").PutValue(2021); sheet.GetCells().Get(u"C9").PutValue(2700);
    int idx1 = sheet.GetPivotTables().Add(u"A1:C9", u"E3", u"Pivot1");
    PivotTable pivotTable1 = sheet.GetPivotTables().Get(idx1);
    pivotTable1.AddFieldToArea(PivotFieldType::Row, u"Fruit");
    pivotTable1.AddFieldToArea(PivotFieldType::Column, u"Year");
    pivotTable1.AddFieldToArea(PivotFieldType::Data, u"Amount");
    int idx2 = sheet.GetPivotTables().Add(u"A1:C9", u"E15", u"Pivot2");
    PivotTable pivotTable2 = sheet.GetPivotTables().Get(idx2);
    pivotTable2.AddFieldToArea(PivotFieldType::Row, u"Fruit");
    pivotTable2.AddFieldToArea(PivotFieldType::Column, u"Year");
    pivotTable2.AddFieldToArea(PivotFieldType::Data, u"Amount");
    sheet.GetCells().Get(u"C2").PutValue(5000);
    sheet.GetCells().Get(u"C5").PutValue(7500);
    sheet.GetCells().Get(u"C9").PutValue(9500);
    pivotTable2.CalculateData();
    wb.Save(u"output.xlsx");
    Aspose::Cells::Cleanup();
    return 0;
}

En arbetsbok innehåller ofta många pivottabeller som alla vilar på ett delat cacheminne. För att räkna upp dem — till exempel innan du utför en batchuppdatering, eller för att diagnostisera påverkan av delade cacheminnen — använd PivotCache.GetPivotTables(). Denna metod returnerar samlingen av varje PivotTable som är beroende av det angivna cacheminnet.

Migrera från den föråldrade PivotTable.RefreshData()

Före Aspose.Cells for C++ v26.7 var standardmetoden för att uppdatera en pivottabell att anropa PivotTable.RefreshData() på varje pivottabell individuellt. Från och med v26.7 är den metoden markerad som föråldrad och bör ersättas med de cache-medvetna API:er som beskrivs ovan. Det finns två skäl till att RefreshData()-metoden per tabell är problematisk i verkliga arbetsböcker:

  • Den hämtar data från källan varje gång den anropas, även när källan inte har ändrats. De rekommenderade ersättningarna är: Följande exempel visar det nya effektiva mönstret för arbetsböcker med flera pivottabeller som delar ett enda cacheminne.

Vilket uppdaterings-API ska jag använda?

Tabellen nedan sammanfattar de tillgängliga uppdaterings-API:erna och när du ska välja var och en.

Mål Rekommenderat API Anteckningar
Uppdatera allt i arbetsboken Workbook.RefreshAll() Ett anrop; täcker alla cacheminnen och tabeller.
Uppdatera endast pivottabeller på ett enskilt kalkylblad Worksheet.RefreshPivotTables() Begränsat till ett kalkylblad.
Källdata har ändrats för ett cacheminne pivotTable.GetPivotCache().Refresh() Uppdaterar ALLA pivottabeller som delar det cacheminnet.
Endast vy-/layoutinställningar har ändrats pivotTable.CalculateData() Hoppar över onödig hämtning från källan.
Lista alla pivottabeller som delar ett cacheminne pivotCache.GetPivotTables() Använd för att räkna upp före massuppdatering.
I praktiken bör du föredra de cache-baserade API:erna framför den föråldrade RefreshData() per tabell. De är medvetna om delade cacheminnen, undviker redundanta källhämtningar och låter dig välja det minsta omfånget som uppfyller ditt uppdateringskrav.

Vanliga fallgropar

  • Glömmer att uppdatera innan spara. En pivottabell skriver bara sina renderade värden till kalkylbladet när dess datakedja är uppdaterad. Om du modifierar källceller, anropa PivotCache.Refresh() (eller Workbook.RefreshAll()) före Workbook.Save(), annars innehåller den sparade filen fortfarande de gamla aggregerade värdena.
  • Anropar den föråldrade RefreshData() per tabell. I v26.7 är PivotTable.RefreshData() markerad som föråldrad och hämtar källan på nytt för varje anrop. Med flera pivottabeller som delar ett cacheminne innebär detta N redundanta källhämtningar. Ersätt med ett enda PivotCache.Refresh() följt av CalculateData() per tabell.
  • Uppdaterar när bara layouten ändrades. Om du bara ändrade en pivottabells vy (kolumnordning, ConsolidationFunction osv.) utan att röra källdatan är PivotCache.Refresh() onödigt och långsamt. Anropa pivotTable.CalculateData() för att rendera om från befintligt cacheminne.
  • Extern källa stöds inte av PivotCache.Refresh(). Om pivottabellens källa kommer från en extern anslutning (databas, OLAP-kub osv.) kan PivotCache.Refresh() inte uppdatera den i v26.7 — den stöder för närvarande endast källtyperna Sheet och Consolidation. För externa källor, öppna arbetsboken igen eller bygg om cacheminnet från källan.
using Aspose.Cells;
Workbook workbook = new Workbook("input.xlsx");
workbook.RefreshAll();
workbook.Save("output.xlsx");