Analyzing your prompt, please hold on...
An error occurred while retrieving the results. Please refresh the page and try again.
PivotTable.RefreshData() помечен как нерекомендуемый и должен быть заменён более эффективными, учитывающими кэш API, описанными в данной статье.
Обновление сводной таблицы редко является одной операцией. За кулисами Aspose.Cells поддерживает многоуровневую цепочку данных, которая соединяет исходные данные с отображаемыми значениями, которые вы видите на рабочем листе. Понимание этой цепочки является ключом к выбору правильного API обновления для любой ситуации.
Четырёхуровневая цепочка данных выглядит так:
PivotCache; здесь все данные собираются и агрегируются.PivotTable считывает данные только из своего PivotCache, но никогда напрямую из источника данных.Cells рабочего листа, в которые PivotTable выводит вычисленные значения и стили.Особенно важным понятием является общий кэш. Когда несколько сводных таблиц в рабочей книге ссылаются на один и тот же исходный диапазон, они совместно используют один экземпляр PivotCache. На один PivotCache могут ссылаться многие сводные таблицы, и обновление этого кэша обновляет все зависимые PivotTable одновременно.
PivotCache.SourceType (перечисление PivotTableSourceType) указывает, откуда поступили данные кэша. Начиная с версии v26.7, PivotCache.Refresh() поддерживает только типы источников Sheet и Consolidation — то есть данные, которые находятся в диапазонах рабочего листа. Внешние источники (базы данных, внешние подключения и т. д.) пока не могут быть обновлены через API кэша.
Из-за этой цепочки в Aspose.Cells существуют два основных пути обновления:
PivotCache.Refresh() — перезагружает источник → кэш И пересчитывает все зависимые PivotTable за одну операцию.PivotTable.CalculateData() — пересчитывает отображение одной PivotTable из уже кэшированных данных, без обратного обращения к источнику данных.Все сценарии в этой статье используют исходные данные из ячеек рабочего листа, поэтому тип источника — Sheet, и операции обновления ведут себя так, как описано.
Все примеры C# в этой статье начинаются со следующих трёх директив using, поскольку типы сводных таблиц находятся в пространстве имён Aspose.Cells.Pivot:
using System;using Aspose.Cells;using Aspose.Cells.Pivot;Если вам необходимо обеспечить, чтобы каждый кэш сводной таблицы и каждая сводная таблица в рабочей книге отражали самые последние исходные данные, самым простым и наиболее полным API является Workbook.RefreshAll(). Один вызов обрабатывает всю рабочую книгу — обновляя каждый PivotCache из его источника и затем пересчитывая каждую зависимую PivotTable. Это рекомендуемый подход для общих полных обновлений документа, когда производительность не критична.
В следующем примере создаётся рабочая книга с исходным диапазоном Fruit/Year/Amount, создаётся одна сводная таблица, изменяются некоторые исходные значения, а затем с помощью RefreshAll() всё приводится в актуальное состояние за один вызов.
using System;
using Aspose.Cells;
using Aspose.Cells.Pivot;
// Создать новую книгу
Workbook workbook = new Workbook();
Worksheet worksheet = workbook.Worksheets[0];
// Записать строку заголовка в ячейки A1:C1
worksheet.Cells["A1"].PutValue("Fruit");
worksheet.Cells["B1"].PutValue("Year");
worksheet.Cells["C1"].PutValue("Amount");
// Записать строки данных в ячейки A2:C9 (8 строк данных о фруктах за 2020 и 2021 годы)
worksheet.Cells["A2"].PutValue("grape");
worksheet.Cells["B2"].PutValue(2020);
worksheet.Cells["C2"].PutValue(50);
worksheet.Cells["A3"].PutValue("blueberry");
worksheet.Cells["B3"].PutValue(2020);
worksheet.Cells["C3"].PutValue(60);
worksheet.Cells["A4"].PutValue("kiwi");
worksheet.Cells["B4"].PutValue(2020);
worksheet.Cells["C4"].PutValue(70);
worksheet.Cells["A5"].PutValue("cherry");
worksheet.Cells["B5"].PutValue(2020);
worksheet.Cells["C5"].PutValue(80);
worksheet.Cells["A6"].PutValue("grape");
worksheet.Cells["B6"].PutValue(2021);
worksheet.Cells["C6"].PutValue(90);
worksheet.Cells["A7"].PutValue("blueberry");
worksheet.Cells["B7"].PutValue(2021);
worksheet.Cells["C7"].PutValue(100);
worksheet.Cells["A8"].PutValue("kiwi");
worksheet.Cells["B8"].PutValue(2021);
worksheet.Cells["C8"].PutValue(110);
worksheet.Cells["A9"].PutValue("cherry");
worksheet.Cells["B9"].PutValue(2021);
worksheet.Cells["C9"].PutValue(120);
// Добавить сводную таблицу: исходный диапазон "A1:C9", ячейка назначения "E3", имя "Pivot1"
int pivotIndex = worksheet.PivotTables.Add("A1:C9", "E3", "Pivot1");
PivotTable pivotTable = worksheet.PivotTables[pivotIndex];
// Назначить поля сводной таблицы: Fruit — в строки, Year — в столбцы, Amount — в данные
pivotTable.AddFieldToArea(PivotFieldType.Row, "Fruit");
pivotTable.AddFieldToArea(PivotFieldType.Column, "Year");
pivotTable.AddFieldToArea(PivotFieldType.Data, "Amount");
// Изменить несколько значений Amount в исходных данных для имитации изменений
worksheet.Cells["C2"].PutValue(55);
worksheet.Cells["C5"].PutValue(85);
worksheet.Cells["C9"].PutValue(125);
// Обновить все сводные таблицы / кэши сводных таблиц в книге
workbook.RefreshAll();
// Сохранить книгу
workbook.Save("output.xlsx");
Иногда вам нужно обновить только те сводные таблицы, которые находятся на одном конкретном рабочем листе — например, когда известно, что сводные таблицы на других рабочих листах не связаны и их не следует трогать. Для этого случая Aspose.Cells предоставляет Worksheet.RefreshPivotTables(), который ограничен одним экземпляром Worksheet.
Этот подход более избирателен, чем Workbook.RefreshAll(): обновляются только сводные таблицы на целевом рабочем листе, а сводные таблицы на других рабочих листах остаются нетронутыми.
В следующем примере заполняются те же исходные данные Fruit/Year/Amount, добавляется сводная таблица на первый рабочий лист, изменяются некоторые исходные значения, а затем обновляются только сводные таблицы на этом рабочем листе.
using System;
using Aspose.Cells;
using Aspose.Cells.Pivot;
Workbook workbook = new Workbook();
Worksheet worksheet = workbook.Worksheets[0];
worksheet.Cells["A1"].PutValue("Fruit");
worksheet.Cells["B1"].PutValue("Year");
worksheet.Cells["C1"].PutValue("Amount");
worksheet.Cells["A2"].PutValue("grape");
worksheet.Cells["B2"].PutValue(2020);
worksheet.Cells["C2"].PutValue(100);
worksheet.Cells["A3"].PutValue("blueberry");
worksheet.Cells["B3"].PutValue(2021);
worksheet.Cells["C3"].PutValue(150);
worksheet.Cells["A4"].PutValue("kiwi");
worksheet.Cells["B4"].PutValue(2020);
worksheet.Cells["C4"].PutValue(200);
worksheet.Cells["A5"].PutValue("cherry");
worksheet.Cells["B5"].PutValue(2021);
worksheet.Cells["C5"].PutValue(120);
worksheet.Cells["A6"].PutValue("grape");
worksheet.Cells["B6"].PutValue(2021);
worksheet.Cells["C6"].PutValue(180);
worksheet.Cells["A7"].PutValue("blueberry");
worksheet.Cells["B7"].PutValue(2020);
worksheet.Cells["C7"].PutValue(130);
worksheet.Cells["A8"].PutValue("kiwi");
worksheet.Cells["B8"].PutValue(2021);
worksheet.Cells["C8"].PutValue(220);
worksheet.Cells["A9"].PutValue("cherry");
worksheet.Cells["B9"].PutValue(2020);
worksheet.Cells["C9"].PutValue(140);
int pivotIndex = worksheet.PivotTables.Add("A1:C9", "E3", "Pivot1");
PivotTable pivotTable = worksheet.PivotTables[pivotIndex];
pivotTable.AddFieldToArea(PivotFieldType.Row, "Fruit");
pivotTable.AddFieldToArea(PivotFieldType.Column, "Year");
pivotTable.AddFieldToArea(PivotFieldType.Data, "Amount");
worksheet.Cells["C2"].PutValue(300);
worksheet.Cells["C5"].PutValue(250);
worksheet.Cells["C9"].PutValue(400);
worksheet.RefreshPivotTables();
workbook.Save("output.xlsx");
Когда вам нужен детальный контроль над одной сводной таблицей, API на основе кэша предоставляет вам два варианта. Выбор между ними зависит от того, что фактически изменилось: базовые исходные данные или только параметры представления/макета самой сводной таблицы.
PivotCache.Refresh()Если базовые исходные данные изменились, правильной точкой входа является pivotTable.PivotCache.Refresh(). Этот вызов перечитывает исходные данные в кэш, а затем пересчитывает все PivotTable, которые зависят от этого кэша.
PivotCache, вызов PivotCache.Refresh() пересчитывает все сводные таблицы, построенные на этом же кэше — не только ту, на которую вы ссылаетесь. Если две сводные таблицы используют один и тот же исходный диапазон, обновление одного кэша обновляет обе.
В следующем примере создаются две сводные таблицы на одном и том же исходном диапазоне, чтобы продемонстрировать это поведение общего кэша, изменяются некоторые исходные значения, а затем выполняется обновление через одну ссылку на кэш.
using System;
using Aspose.Cells;
using Aspose.Cells.Pivot;
// Создаём новую книгу и получаем доступ к первому листу
Workbook workbook = new Workbook();
Worksheet worksheet = workbook.Worksheets[0];
// Записываем строку заголовков: Fruit / Year / Amount
worksheet.Cells["A1"].PutValue("Fruit");
worksheet.Cells["B1"].PutValue("Year");
worksheet.Cells["C1"].PutValue("Amount");
// Записываем примерно 9 строк данных (grape / blueberry / kiwi / cherry за 2020-2021)
worksheet.Cells["A2"].PutValue("Grape");
worksheet.Cells["B2"].PutValue(2020);
worksheet.Cells["C2"].PutValue(100);
worksheet.Cells["A3"].PutValue("Blueberry");
worksheet.Cells["B3"].PutValue(2020);
worksheet.Cells["C3"].PutValue(200);
worksheet.Cells["A4"].PutValue("Kiwi");
worksheet.Cells["B4"].PutValue(2020);
worksheet.Cells["C4"].PutValue(300);
worksheet.Cells["A5"].PutValue("Cherry");
worksheet.Cells["B5"].PutValue(2020);
worksheet.Cells["C5"].PutValue(400);
worksheet.Cells["A6"].PutValue("Grape");
worksheet.Cells["B6"].PutValue(2021);
worksheet.Cells["C6"].PutValue(500);
worksheet.Cells["A7"].PutValue("Blueberry");
worksheet.Cells["B7"].PutValue(2021);
worksheet.Cells["C7"].PutValue(600);
worksheet.Cells["A8"].PutValue("Kiwi");
worksheet.Cells["B8"].PutValue(2021);
worksheet.Cells["C8"].PutValue(700);
worksheet.Cells["A9"].PutValue("Cherry");
worksheet.Cells["B9"].PutValue(2021);
worksheet.Cells["C9"].PutValue(800);
// Добавляем первую сводную таблицу "Pivot1" с якорем в ячейке E3, исходный диапазон A1:C9
int pivotIndex1 = worksheet.PivotTables.Add("A1:C9", "E3", "Pivot1");
PivotTable pivotTable1 = worksheet.PivotTables[pivotIndex1];
// Назначаем поля для Pivot1
pivotTable1.AddFieldToArea(PivotFieldType.Row, "Fruit");
pivotTable1.AddFieldToArea(PivotFieldType.Column, "Year");
pivotTable1.AddFieldToArea(PivotFieldType.Data, "Amount");
// Добавляем ВТОРУЮ сводную таблицу "Pivot2" с якорем в E15, используя ТОТ ЖЕ исходный диапазон A1:C9
// Pivot1 и Pivot2 используют общий PivotCache, так как исходный диапазон идентичен.
int pivotIndex2 = worksheet.PivotTables.Add("A1:C9", "E15", "Pivot2");
PivotTable pivotTable2 = worksheet.PivotTables[pivotIndex2];
// Назначаем те же поля для Pivot2
pivotTable2.AddFieldToArea(PivotFieldType.Row, "Fruit");
pivotTable2.AddFieldToArea(PivotFieldType.Column, "Year");
pivotTable2.AddFieldToArea(PivotFieldType.Data, "Amount");
// Изменяем несколько значений ячеек Amount в исходных данных для имитации изменения данных
worksheet.Cells["C2"].PutValue(150);
worksheet.Cells["C4"].PutValue(350);
worksheet.Cells["C7"].PutValue(650);
// Обновляем общий PivotCache.
// Поскольку Pivot1 и Pivot2 используют общий PivotCache, этот единственный вызов
// обновляет ОБЕ сводные таблицы (данные + стиль) из обновлённого источника.
pivotTable1.PivotCache.Refresh();
// Сохраняем книгу
workbook.Save("output.xlsx");
CalculateData()Если исходные данные не изменились, но изменились только параметры представления или макета сводной таблицы (например, поле было перемещено в другую область или был переключён параметр обновления при открытии), нет необходимости выполнять обратное обращение к источнику данных. Кэш уже содержит правильные данные; необходимо только пересчитать отображаемую PivotTable. В этом случае правильным выбором является pivotTable.CalculateData().
Это позволяет избежать ненужного извлечения из источника и значительно быстрее, когда много сводных таблиц совместно используют один и тот же кэш.
В следующем примере изменяется свойство сводной таблицы, не связанное с источником, а затем вызывается CalculateData() для повторного отображения из существующего кэша.
using Aspose.Cells;
using Aspose.Cells.Pivot;
var workbook = new Workbook();
var worksheet = workbook.Worksheets[0];
// Записать строку заголовка Fruit / Year / Amount
worksheet.Cells["A1"].PutValue("Fruit");
worksheet.Cells["B1"].PutValue("Year");
worksheet.Cells["C1"].PutValue("Amount");
// Записать 8 строк данных (строки 2-9, соответствует исходному диапазону A1:C9)
worksheet.Cells["A2"].PutValue("Grape");
worksheet.Cells["B2"].PutValue(2020);
worksheet.Cells["C2"].PutValue(100);
worksheet.Cells["A3"].PutValue("Blueberry");
worksheet.Cells["B3"].PutValue(2020);
worksheet.Cells["C3"].PutValue(200);
worksheet.Cells["A4"].PutValue("Kiwi");
worksheet.Cells["B4"].PutValue(2020);
worksheet.Cells["C4"].PutValue(300);
worksheet.Cells["A5"].PutValue("Cherry");
worksheet.Cells["B5"].PutValue(2020);
worksheet.Cells["C5"].PutValue(400);
worksheet.Cells["A6"].PutValue("Grape");
worksheet.Cells["B6"].PutValue(2021);
worksheet.Cells["C6"].PutValue(150);
worksheet.Cells["A7"].PutValue("Blueberry");
worksheet.Cells["B7"].PutValue(2021);
worksheet.Cells["C7"].PutValue(250);
worksheet.Cells["A8"].PutValue("Kiwi");
worksheet.Cells["B8"].PutValue(2021);
worksheet.Cells["C8"].PutValue(350);
worksheet.Cells["A9"].PutValue("Cherry");
worksheet.Cells["B9"].PutValue(2021);
worksheet.Cells["C9"].PutValue(450);
// Добавить сводную таблицу с именем "Pivot1", размещённую в ячейке назначения E3, с источником A1:C9
int pivotIndex = worksheet.PivotTables.Add("A1:C9", "E3", "Pivot1");
var pivotTable = worksheet.PivotTables[pivotIndex];
// Назначить поля: Fruit — в строки, Year — в столбцы, Amount — в данные
pivotTable.AddFieldToArea(PivotFieldType.Row, "Fruit");
pivotTable.AddFieldToArea(PivotFieldType.Column, "Year");
pivotTable.AddFieldToArea(PivotFieldType.Data, "Amount");
// Изменить свойство представления/макета — это изменение только для отображения,
// поэтому оно НЕ требует повторного чтения исходных данных через PivotCache.Refresh().
pivotTable.RefreshDataOnOpeningFile = false;
// CalculateData() повторно отображает представление ЭТОЙ сводной таблицы (данные + стиль) из
// данных, уже находящихся в PivotCache. Поскольку исходные данные не изменились,
// обращения к источнику не происходит — пересчитываются только кэшированные значения
// и помещаются в ячейки листа.
pivotTable.CalculateData();
// Сохранить книгу на диск
workbook.Save("output.xlsx");
Рабочая книга часто содержит много сводных таблиц, которые все расположены поверх одного общего кэша. Чтобы перечислить их — например, перед выполнением пакетного обновления или для диагностики влияния общего кэша — используйте PivotCache.GetPivotTables(). Этот метод возвращает коллекцию каждой PivotTable, которая зависит от данного кэша.
Это также самый прямой способ убедиться, что две сводные таблицы действительно совместно используют один и тот же экземпляр PivotCache: вы можете сравнить ссылки на кэш или просто перебрать коллекцию, возвращаемую GetPivotTables(), и увидеть, какие сводные таблицы в ней присутствуют.
В следующем примере создаются две сводные таблицы на одном и том же исходном диапазоне, проверяется, что они совместно используют один и тот же экземпляр кэша, а затем перечисляются сводные таблицы этого кэша.
PivotTable.RefreshData()До Aspose.Cells for .NET v26.7 стандартным способом обновления сводной таблицы был вызов PivotTable.RefreshData() для каждой сводной таблицы по отдельности. Начиная с версии v26.7 этот метод помечен как нерекомендуемый и должен быть заменён API, учитывающими кэш, которые описаны выше.
Есть две причины, по которым подход с индивидуальным вызовом RefreshData() для каждой таблицы является проблематичным в реальных рабочих книгах:
RefreshData() для каждой сводной таблицы приводит к повторному извлечению одного и того же кэша, что очень медленно.Рекомендуемые замены:
workbook.RefreshAll();pivotTable.PivotCache.Refresh(); для одного кэша. Поскольку кэш является общим, этот единственный вызов обновляет каждую сводную таблицу, построенную поверх этого кэша. Другие сводные таблицы, использующие уже обновлённый кэш, можно безопасно пропустить.pivotTable.CalculateData(); для повторного отображения из существующего кэша без какого-либо обращения к источнику.В следующем примере демонстрируется новый эффективный шаблон для рабочих книг с несколькими сводными таблицами, использующими один кэш.
В таблице ниже приведены доступные API обновления и указано, когда следует выбирать каждый из них.
| Цель | Рекомендуемый API | Примечания |
|---|---|---|
| Обновить всё в рабочей книге | Workbook.RefreshAll() |
Один вызов; охватывает все кэши и таблицы. |
| Обновить только сводные таблицы на одном листе | Worksheet.RefreshPivotTables() |
Ограничено одним рабочим листом. |
| Исходные данные для одного кэша изменились | pivotTable.PivotCache.Refresh() |
Обновляет ВСЕ сводные таблицы на этом общем кэше. |
| Изменились только параметры представления/макета | pivotTable.CalculateData() |
Пропускает ненужное обращение к источнику. |
| Список всех сводных таблиц на общем кэше | pivotCache.GetPivotTables() |
Используйте для перечисления перед массовым обновлением. |
На практике отдавайте предпочтение API на основе кэша вместо устаревшего подхода с вызовом RefreshData() для каждой таблицы. Они учитывают общие кэши, избегают избыточных извлечений из источника и позволяют выбрать наименьший объём, удовлетворяющий вашим требованиям к обновлению.
Analyzing your prompt, please hold on...
An error occurred while retrieving the results. Please refresh the page and try again.