Управление рабочими книгами диаграмм в презентациях на Android
Обзор
В этой статье объясняется, как работать с рабочими книгами диаграмм в Aspose.Slides. Описывается, как читать и записывать данные диаграмм через потоки рабочих книг, использовать ячейки рабочей книги в качестве меток данных диаграммы, получать доступ к коллекциям листов и указывать тип источника данных для значений диаграмм. Также рассматривается работа с внешними рабочими книгами в качестве источников данных для диаграмм. В примерах демонстрируется, как создать и назначить внешнюю рабочую книгу, получить путь к внешней рабочей книге, связанной с диаграммой, и редактировать данные диаграммы, когда рабочая книга доступна.
Чтение и запись данных диаграммы из рабочей книги
Aspose.Slides предоставляет методы ReadWorkbookStream и WriteWorkbookStream , позволяющие читать и записывать рабочие книги с данными диаграмм (содержащие данные диаграмм, отредактированные с помощью Aspose.Cells). Примечание: данные диаграммы должны быть организованы таким же образом или иметь структуру, схожую с исходной.
import com.aspose.slides.*;
Presentation pres = new Presentation("chart.pptx");
try {
Chart chart = (Chart) pres.getSlides().get_Item(0).getShapes().get_Item(0);
IChartData data = chart.getChartData();
byte[] stream = data.readWorkbookStream();
data.getSeries().clear();
data.getCategories().clear();
data.writeWorkbookStream(stream);
} finally {
if (pres != null) pres.dispose();
}
Проверка расположения диаграммы после изменения рабочей книги
Когда вы заменяете встроенную рабочую книгу измененной, диаграмма сохраняет свои исходные коллекции серий и категорий. Такое несоответствие может привести к сбою IChart.validateChartLayout с ошибкой выхода индекса за пределы. Очистите существующие серии и категории перед записью обновлённой рабочей книги обратно в диаграмму.
// После изменения потока рабочей книги (например, с помощью Aspose.Cells)
byte[] updatedWorkbook = chartData.readWorkbookStream();
// Очистить существующие ссылки данных.
chartData.getSeries().clear();
chartData.getCategories().clear();
chartData.writeWorkbookStream(updatedWorkbook);
chart.validateChartLayout();
Очистка коллекций гарантирует, что структура данных диаграммы соответствует новой рабочей книге, позволяя validateChartLayout завершиться без ошибок.
Установить ячейку рабочей книги в качестве метки данных диаграммы
- Создайте экземпляр класса Presentation .
- Получите ссылку на слайд по его индексу.
- Добавьте пузырьковую диаграмму с некоторыми данными.
- Получите доступ к сериям диаграммы.
- Установите ячейку рабочей книги в качестве метки данных.
- Сохраните презентацию.
Этот код на Java показывает, как установить ячейку рабочей книги в качестве метки данных диаграммы:
import com.aspose.slides.*;
String lbl0 = "Label 0 cell value";
String lbl1 = "Label 1 cell value";
String lbl2 = "Label 2 cell value";
// Создаёт экземпляр класса презентации, представляющего файл презентации
Presentation pres = new Presentation("chart2.pptx");
try {
ISlide slide = pres.getSlides().get_Item(0);
IChart chart = slide.getShapes().addChart(ChartType.Bubble, 50, 50, 600, 400, true);
IChartSeriesCollection series = chart.getChartData().getSeries();
IDataLabelCollection dataLabelCollection = series.get_Item(0).getLabels();
dataLabelCollection.getDefaultDataLabelFormat().setShowLabelValueFromCell(true);
IChartDataWorkbook wb = chart.getChartData().getChartDataWorkbook();
dataLabelCollection.get_Item(0).setValueFromCell(wb.getCell(0, "A10", lbl0));
dataLabelCollection.get_Item(1).setValueFromCell(wb.getCell(0, "A11", lbl1));
dataLabelCollection.get_Item(2).setValueFromCell(wb.getCell(0, "A12", lbl2));
pres.save("resultchart.pptx", SaveFormat.Pptx);
} finally {
if (pres != null) pres.dispose();
}
Управление листами
Этот код на Java демонстрирует операцию, где метод IChartDataWorkbook.Worksheets используется для доступа к коллекции листов:
import com.aspose.slides.*;
Presentation pres = new Presentation();
try {
IChart chart = pres.getSlides().get_Item(0).getShapes().addChart(ChartType.Pie, 50, 50, 400, 500);
IChartDataWorkbook wb = chart.getChartData().getChartDataWorkbook();
for (int i = 0; i < wb.getWorksheets().size(); i++)
System.out.println(wb.getWorksheets().get_Item(i).getName());
} finally {
if (pres != null) pres.dispose();
}
Указание типа источника данных
Этот код на Java показывает, как указать тип для источника данных:
import com.aspose.slides.*;
Presentation pres = new Presentation();
try {
IChart chart = pres.getSlides().get_Item(0).getShapes().addChart(ChartType.Column3D, 50, 50, 600, 400, true);
IStringChartValue val = chart.getChartData().getSeries().get_Item(0).getName();
val.setDataSourceType(DataSourceType.StringLiterals);
val.setData("LiteralString");
val = chart.getChartData().getSeries().get_Item(1).getName();
val.setData(chart.getChartData().getChartDataWorkbook().getCell(0, "B1", "NewCell"));
pres.save("pres.pptx", SaveFormat.Pptx);
} finally {
if (pres != null) pres.dispose();
}
Обнаружение неподдерживаемых форматов встроенных рабочих книг
Aspose.Slides не поддерживает двоичный формат рабочей книги Excel (.xlsb), который может быть встроен в некоторые диаграммы. Вы можете использовать метод getEmbeddedWorkbookType интерфейса IChartData вместе с перечислением WorkbookType для обнаружения неподдерживаемых форматов и пропуска таких диаграмм.
import com.aspose.slides.*;
Presentation presentation = new Presentation("sample.pptx");
try {
ISlide slide = presentation.getSlides().get_Item(0);
for (IShape shape : slide.getShapes()) {
if (!(shape instanceof IChart)) continue;
IChart chart = (IChart)shape;
IChartData chartData = chart.getChartData();
if (chartData.getDataSourceType() == ChartDataSourceType.InternalWorkbook &&
chartData.getEmbeddedWorkbookType() == WorkbookType.WorkbookBinaryMacro) {
// Встроенная рабочая книга в формате .xlsb, который не поддерживается.
continue;
}
// Здесь можно читать или изменять данные рабочей книги диаграммы.
}
} finally {
presentation.dispose();
}
Внешняя рабочая книга
Aspose.Slides поддерживает внешние рабочие книги в качестве источника данных для диаграмм.
Создание внешней рабочей книги
С помощью методов readWorkbookStream и setExternalWorkbook вы можете либо создать внешнюю рабочую книгу с нуля, либо превратить внутреннюю рабочую книгу во внешнюю.
Этот код на Java демонстрирует процесс создания внешней рабочей книги:
import com.aspose.slides.*;
import java.io.FileOutputStream;
import java.io.IOException;
Presentation pres = new Presentation();
try {
final String workbookPath = "externalWorkbook1.xlsx";
IChart chart = pres.getSlides().get_Item(0).getShapes().addChart(ChartType.Pie, 50, 50, 400, 600);
FileOutputStream fileStream = new FileOutputStream(workbookPath);
try {
byte[] workbookData = chart.getChartData().readWorkbookStream();
fileStream.write(workbookData, 0, workbookData.length);
} finally {
if (fileStream != null) fileStream.close();
}
chart.getChartData().setExternalWorkbook(workbookPath);
pres.save("externalWorkbook.pptx", SaveFormat.Pptx);
} catch (IOException e) {
} finally {
if (pres != null) pres.dispose();
}
Назначение внешней рабочей книги
С помощью метода setExternalWorkbook вы можете назначить внешнюю рабочую книгу диаграмме в качестве её источника данных. Этот метод также можно использовать для обновления пути к внешней рабочей книге (если она была перемещена).
Хотя вы не можете редактировать данные в рабочих книгах, хранящихся в удалённых местах или ресурсах, их всё равно можно использовать в качестве внешнего источника данных. Если указан относительный путь к внешней рабочей книге, он автоматически преобразуется в абсолютный путь.
Этот код на Java показывает, как назначить внешнюю рабочую книгу:
import com.aspose.slides.*;
// Создаёт экземпляр класса Presentation
Presentation pres = new Presentation("chart.pptx");
try {
IChart chart = pres.getSlides().get_Item(0).getShapes().addChart(ChartType.Pie, 50, 50, 400, 600, false);
IChartData chartData = chart.getChartData();
chartData.setExternalWorkbook("externalWorkbook.xlsx");
chartData.getSeries().add(chartData.getChartDataWorkbook().getCell(0, "B1"), ChartType.Pie);
chartData.getSeries().get_Item(0).getDataPoints().addDataPointForPieSeries(chartData.getChartDataWorkbook().getCell(0, "B2"));
chartData.getSeries().get_Item(0).getDataPoints().addDataPointForPieSeries(chartData.getChartDataWorkbook().getCell(0, "B3"));
chartData.getSeries().get_Item(0).getDataPoints().addDataPointForPieSeries(chartData.getChartDataWorkbook().getCell(0, "B4"));
chartData.getCategories().add(chartData.getChartDataWorkbook().getCell(0, "A2"));
chartData.getCategories().add(chartData.getChartDataWorkbook().getCell(0, "A3"));
chartData.getCategories().add(chartData.getChartDataWorkbook().getCell(0, "A4"));
pres.save("Presentation_with_externalWorkbook.pptx", SaveFormat.Pptx);
} finally {
if (pres != null) pres.dispose();
}
Параметр updateChartData (в методе setExternalWorkbook) используется для указания, будет ли Excel‑рабочая книга загружена.
- Когда значение
updateChartDataустановлено вfalse, обновляется только путь к рабочей книге — данные диаграммы не будут загружаться и обновляться из целевой рабочей книги. Это настройку удобно использовать, если целевая рабочая книга отсутствует или недоступна. - Когда значение
updateChartDataустановлено вtrue, данные диаграммы обновляются из целевой рабочей книги.
import com.aspose.slides.*;
// Создаёт экземпляр класса Presentation
Presentation pres = new Presentation("chart.pptx");
try {
IChart chart = pres.getSlides().get_Item(0).getShapes().addChart(ChartType.Pie, 50, 50, 400, 600, true);
IChartData chartData = chart.getChartData();
((ChartData)chartData).setExternalWorkbook("http://path/doesnt/exists", false);
pres.save("Presentation_with_externalWorkbookWithUpdateChartData.pptx", SaveFormat.Pptx);
} finally {
if (pres != null) pres.dispose();
}
Получение пути к внешней рабочей книге-источнику данных диаграммы
- Создайте экземпляр класса Presentation .
- Получите ссылку на слайд по его индексу.
- Создайте объект для формы диаграммы.
- Создайте объект типа источника (
ChartDataSourceType), представляющего источник данных диаграммы. - Укажите соответствующее условие, основанное на том, что тип источника совпадает с типом внешней рабочей книги.
Этот код на Java демонстрирует операцию:
import com.aspose.slides.*;
// Создаёт экземпляр класса Presentation
Presentation pres = new Presentation("chart.pptx");
try {
ISlide slide = pres.getSlides().get_Item(1);
IChart chart = (IChart)slide.getShapes().get_Item(0);
int sourceType = chart.getChartData().getDataSourceType();
if (sourceType == ChartDataSourceType.ExternalWorkbook)
{
String path = chart.getChartData().getExternalWorkbookPath();
}
// Сохраняет презентацию
pres.save("result.pptx", SaveFormat.Pptx);
} finally {
if (pres != null) pres.dispose();
}
Редактирование данных диаграммы
Вы можете редактировать данные во внешних рабочих книгах так же, как вносите изменения в содержимое внутренних книг. Если внешняя рабочая книга не может быть загружена, генерируется исключение.
Этот код на Java реализует описанный процесс:
import com.aspose.slides.*;
// Создаёт экземпляр класса Presentation
Presentation pres = new Presentation("chart.pptx");
try {
IChart chart = (IChart)pres.getSlides().get_Item(0).getShapes().get_Item(0);
ChartData chartData = (ChartData)chart.getChartData();
chartData.getSeries().get_Item(0).getDataPoints().get_Item(0).getValue().getAsCell().setValue(100);
pres.save("presentation_out.pptx", SaveFormat.Pptx);
} finally {
if (pres != null) pres.dispose();
}
Восстановление рабочей книги из кэша диаграммы
Если диаграмма использует внешнюю рабочую книгу, которой нет или она недоступна, Aspose.Slides может воссоздать рабочую книгу диаграммы из данных, кэшированных в презентации. Создайте LoadOptions, настройте его с помощью SpreadsheetOptions, и вызовите ISpreadsheetOptions.setRecoverWorkbookFromChartCache со значением true перед открытием презентации.
Следующий пример на Java открывает презентацию, в которой диаграмма ссылается на недоступную внешнюю рабочую книгу, и получает восстановленные данные через IChart.getChartData и IChartData.getChartDataWorkbook:
import com.aspose.slides.*;
SpreadsheetOptions spreadsheetOptions = new SpreadsheetOptions();
spreadsheetOptions.setRecoverWorkbookFromChartCache(true);
LoadOptions loadOptions = new LoadOptions();
loadOptions.setSpreadsheetOptions(spreadsheetOptions);
Presentation presentation = new Presentation("presentation.pptx", loadOptions);
try {
IChart chart = (IChart)presentation.getSlides().get_Item(0).getShapes().get_Item(0);
IChartDataWorkbook recoveredWorkbook = chart.getChartData().getChartDataWorkbook();
// Здесь читаем или изменяем восстановленные данные рабочей книги.
} finally {
presentation.dispose();
}
Если внешняя рабочая книга недоступна и восстановление отключено, Aspose.Slides генерирует исключение. Включайте восстановление только тогда, когда использование кэшированных данных диаграммы является приемлемой альтернативой, так как кэш может не содержать изменения, внесённые во внешнюю рабочую книгу после последнего обновления презентации.
FAQ
Могу ли я определить, связана ли конкретная диаграмма с внешней или встроенной рабочей книгой?
Да. У диаграммы есть тип источника данных и путь к внешней рабочей книге; если источник — внешняя рабочая книга, вы можете прочитать полный путь, чтобы убедиться, что используется внешний файл.
Поддерживаются ли относительные пути к внешним рабочим книгам, и как они хранятся?
Да. Если указать относительный путь, он автоматически преобразуется в абсолютный. Это удобно для переносимости проекта; однако следует учитывать, что презентация сохраняет абсолютный путь в файле PPTX.
Можно ли использовать рабочие книги, расположенные на сетевых ресурсах/общих папках?
Да, такие рабочие книги можно использовать в качестве внешнего источника данных. Однако редактировать удалённые рабочие книги напрямую из Aspose.Slides не поддерживается — они могут использоваться только как источник.
Перезаписывает ли Aspose.Slides внешний файл XLSX при сохранении презентации?
Нет. Презентация сохраняет ссылку на внешний файл и использует её для чтения данных. Сам внешний файл не изменяется при сохранении презентации.
Что делать, если внешний файл защищён паролем?
Aspose.Slides не принимает пароль при создании ссылки. Обычно предварительно снимают защиту или подготавливают расшифрованную копию (например, с помощью Aspose.Cells) и связывают её.
Может ли несколько диаграмм ссылаться на одну и ту же внешнюю рабочую книгу?
Да. Каждая диаграмма хранит свою собственную ссылку. Если все они указывают на один и тот же файл, обновление этого файла отразится в каждой диаграмме при следующей загрузке данных.