Управление рабочими книгами диаграмм в презентациях с использованием JavaScript

Обзор

В этой статье объясняется, как работать с рабочими книгами диаграмм в Aspose.Slides. Описывается, как считывать и записывать данные диаграммы через потоки рабочей книги, использовать ячейки рабочей книги в качестве меток данных, получать доступ к коллекциям листов и указывать тип источника данных для значений диаграммы.

Также рассматривается работа с внешними рабочими книгами в качестве источников данных диаграмм. Примеры показывают, как создать и назначить внешнюю рабочую книгу, получить путь к внешней рабочей книге, связанной с диаграммой, и редактировать данные диаграммы, когда рабочая книга доступна.

Чтение и запись данных диаграммы из рабочей книги

Aspose.Slides предоставляет методы readWorkbookStream и writeWorkbookStream , позволяющие считывать и записывать рабочие книги данных диаграмм (содержащие данные, отредактированные с помощью Aspose.Cells). Примечание: данные диаграммы должны быть организованы одинаково или иметь структуру, аналогичную источнику.

Этот JavaScript‑код демонстрирует пример операции:

var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");

var pres = new aspose.slides.Presentation("chart.pptx");
try {
    var chart = pres.getSlides().get_Item(0).getShapes().get_Item(0);
    var data = chart.getChartData();
    var stream = data.readWorkbookStream();
    data.getSeries().clear();
    data.getCategories().clear();
    data.writeWorkbookStream(stream);
} finally {
    if (pres != null) {
        pres.dispose();
    }
}

Проверка макета диаграммы после изменения рабочей книги

При замене внедрённой рабочей книги на изменённую диаграмма сохраняет свои оригинальные коллекции серий и категорий. Это несоответствие может привести к ошибке Chart.validateChartLayout с указанием выхода индекса за пределы. Очистите существующие серии и категории перед записью обновлённой рабочей книги обратно в диаграмму.

// После изменения потока рабочей книги (например, с помощью Aspose.Cells)
var updatedWorkbook = chartData.readWorkbookStream();

// Очистить существующие ссылки на данные.
chartData.getSeries().clear();
chartData.getCategories().clear();

chartData.writeWorkbookStream(updatedWorkbook);

chart.validateChartLayout();

Очистка коллекций гарантирует согласованность структуры данных диаграммы с новой рабочей книгой, позволяя validateChartLayout выполниться без ошибок.

Установка ячейки WorkBook в качестве метки данных диаграммы

  1. Создайте экземпляр класса Presentation.
  2. Получите ссылку на слайд по его индексу.
  3. Добавьте пузырьковую диаграмму с некоторыми данными.
  4. Получите доступ к сериям диаграммы.
  5. Установите ячейку рабочей книги в качестве метки данных.
  6. Сохраните презентацию.

Этот JavaScript‑код показывает, как установить ячейку рабочей книги в качестве метки данных диаграммы:

var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");

var lbl0 = "Label 0 cell value";
var lbl1 = "Label 1 cell value";
var lbl2 = "Label 2 cell value";
// Создаёт экземпляр класса презентации, представляющего файл презентации
var pres = new aspose.slides.Presentation("chart2.pptx");
try {
    var slide = pres.getSlides().get_Item(0);
    var chart = slide.getShapes().addChart(aspose.slides.ChartType.Bubble, 50, 50, 600, 400, true);
    var series = chart.getChartData().getSeries();
    var dataLabelCollection = series.get_Item(0).getLabels();
    dataLabelCollection.getDefaultDataLabelFormat().setShowLabelValueFromCell(true);
    var 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", aspose.slides.SaveFormat.Pptx);
} finally {
    if (pres != null) {
        pres.dispose();
    }
}

Управление листами

Этот JavaScript‑код демонстрирует операцию, в которой используется метод ChartDataWorkbook.getWorksheets для доступа к коллекции листов:

var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");

var pres = new aspose.slides.Presentation();
try {
    var chart = pres.getSlides().get_Item(0).getShapes().addChart(aspose.slides.ChartType.Pie, 50, 50, 400, 500);
    var wb = chart.getChartData().getChartDataWorkbook();
    for (var i = 0; i < wb.getWorksheets().size(); i++) {
        console.log(wb.getWorksheets().get_Item(i).getName());
    }
} finally {
    if (pres != null) {
        pres.dispose();
    }
}

Указание типа источника данных

Этот JavaScript‑код показывает, как указать тип для источника данных:

var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");

var pres = new aspose.slides.Presentation();
try {
    var chart = pres.getSlides().get_Item(0).getShapes().addChart(aspose.slides.ChartType.Column3D, 50, 50, 600, 400, true);
    var val = chart.getChartData().getSeries().get_Item(0).getName();
    val.setDataSourceType(aspose.slides.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", aspose.slides.SaveFormat.Pptx);
} finally {
    if (pres != null) {
        pres.dispose();
    }
}

Обнаружение неподдерживаемых форматов внедрённых рабочих книг

Aspose.Slides не поддерживает формат двоичной рабочей книги Excel (.xlsb), который может быть внедрён в некоторые диаграммы. Вы можете использовать метод getEmbeddedWorkbookType класса ChartData совместно с перечислением WorkbookType для обнаружения неподдерживаемых форматов и пропуска соответствующих диаграмм.

var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");

let presentation = new aspose.slides.Presentation("sample.pptx");
try {
    let slide = presentation.getSlides().get_Item(0);
    let shapes = slide.getShapes();

    for (let shapeIndex = 0; shapeIndex < shapes.size(); shapeIndex++) {
        let shape = shapes.get_Item(shapeIndex);

        if (!java.instanceOf(shape, "com.aspose.slides.IChart")) continue;

        let chart = shape;
        let chartData = chart.getChartData();

        if (chartData.getDataSourceType() == aspose.slides.ChartDataSourceType.InternalWorkbook &&
                chartData.getEmbeddedWorkbookType() == aspose.slides.WorkbookType.WorkbookBinaryMacro) {
            // Внедрённая рабочая книга имеет формат .xlsb, который не поддерживается.
            continue;
        }

        // Считать или изменить данные рабочей книги диаграммы здесь.
    }
} finally {
    presentation.dispose();
}

Внешняя рабочая книга

Aspose.Slides поддерживает внешние рабочие книги в качестве источника данных для диаграмм.

Создание внешней рабочей книги

С помощью методов readWorkbookStream и setExternalWorkbook вы можете либо создать внешнюю рабочую книгу с нуля, либо сделать внутреннюю рабочую книгу внешней.

Этот JavaScript‑код демонстрирует процесс создания внешней рабочей книги:

var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const fileSystem = require("fs");

var pres = new aspose.slides.Presentation();
try {
    var workbookPath = "externalWorkbook1.xlsx";
    var chart = pres.getSlides().get_Item(0).getShapes().addChart(aspose.slides.ChartType.Pie, 50, 50, 400, 600);
    // readWorkbookStream возвращает байты рабочей книги как Buffer Node.
    var workbookData = chart.getChartData().readWorkbookStream();
    fileSystem.writeFileSync(workbookPath, Buffer.from(workbookData));
    chart.getChartData().setExternalWorkbook(workbookPath);
    pres.save("externalWorkbook.pptx", aspose.slides.SaveFormat.Pptx);
} catch (e) {console.log(e);
} finally {
    if (pres != null) {
        pres.dispose();
    }
}

Установка внешней рабочей книги

Метод setExternalWorkbook позволяет назначить внешнюю рабочую книгу диаграмме в качестве её источника данных. Этот же метод можно использовать для обновления пути к внешней рабочей книге (если она была перемещена).

Хотя редактировать данные в рабочих книгах, хранящихся в удалённых местах или ресурсах, нельзя, их всё равно можно использовать как внешний источник данных. Если указан относительный путь к внешней рабочей книге, он автоматически преобразуется в полный путь.

Этот JavaScript‑код показывает, как задать внешнюю рабочую книгу:

var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");

// Создаёт экземпляр класса Presentation
var pres = new aspose.slides.Presentation("chart.pptx");
try {
    var chart = pres.getSlides().get_Item(0).getShapes().addChart(aspose.slides.ChartType.Pie, 50, 50, 400, 600, false);
    var chartData = chart.getChartData();
    chartData.setExternalWorkbook("externalWorkbook.xlsx");
    chartData.getSeries().add(chartData.getChartDataWorkbook().getCell(0, "B1"), aspose.slides.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", aspose.slides.SaveFormat.Pptx);
} finally {
    if (pres != null) {
        pres.dispose();
    }
}

Второй параметр метода setExternalWorkbook, updateChartData, указывает, будет ли загружена Excel‑рабочая книга.

  • При updateChartData = false обновляется только путь к рабочей книге — данные диаграммы не загружаются и не обновляются из целевой рабочей книги. Этот вариант полезен, когда целевая рабочая книга отсутствует или недоступна.
  • При updateChartData = true данные диаграммы обновляются из целевой рабочей книги.
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");

// Создаёт экземпляр класса Presentation
var pres = new aspose.slides.Presentation("chart.pptx");
try {
    var chart = pres.getSlides().get_Item(0).getShapes().addChart(aspose.slides.ChartType.Pie, 50, 50, 400, 600, true);
    var chartData = chart.getChartData();
    chartData.setExternalWorkbook("http://path/doesnt/exists", false);
    pres.save("Presentation_with_externalWorkbookWithUpdateChartData.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
    if (pres != null) {
        pres.dispose();
    }
}

Получение пути к внешнему источнику данных диаграммы

  1. Создайте экземпляр класса Presentation.
  2. Получите ссылку на слайд по его индексу.
  3. Создайте объект для формы диаграммы.
  4. Создайте объект типа источника (ChartDataSourceType), представляющего источник данных диаграммы.
  5. Укажите соответствующее условие, исходя из того, что тип источника совпадает с типом внешней рабочей книги.

Этот JavaScript‑код демонстрирует операцию:

var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");

// Создаёт экземпляр класса Presentation
var pres = new aspose.slides.Presentation("chart.pptx");
try {
    var slide = pres.getSlides().get_Item(1);
    var chart = slide.getShapes().get_Item(0);
    var sourceType = chart.getChartData().getDataSourceType();
    if (sourceType == aspose.slides.ChartDataSourceType.ExternalWorkbook) {
        var path = chart.getChartData().getExternalWorkbookPath();
    }
    // Сохраняет презентацию
    pres.save("result.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
    if (pres != null) {
        pres.dispose();
    }
}

Редактирование данных диаграммы

Вы можете редактировать данные во внешних рабочих книгах так же, как и во внутренних. Когда внешняя рабочая книга не может быть загружена, генерируется исключение.

Этот JavaScript‑код реализует описанный процесс:

var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");

// Создаёт экземпляр класса Presentation
var pres = new aspose.slides.Presentation("chart.pptx");
try {
    var chart = pres.getSlides().get_Item(0).getShapes().get_Item(0);
    var chartData = chart.getChartData();
    chartData.getSeries().get_Item(0).getDataPoints().get_Item(0).getValue().getAsCell().setValue(100);
    pres.save("presentation_out.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
    if (pres != null) {
        pres.dispose();
    }
}

Восстановление рабочей книги из кеша диаграммы

Если диаграмма использует внешнюю рабочую книгу, которой нет или она недоступна, Aspose.Slides может восстановить рабочую книгу диаграммы из данных, закешированных в презентации. Создайте LoadOptions, настройте его с помощью SpreadsheetOptions, и вызовите SpreadsheetOptions.setRecoverWorkbookFromChartCache со значением true перед открытием презентации.

Следующий пример JavaScript открывает презентацию, в которой диаграмма ссылается на недоступную внешнюю рабочую книгу, и получает восстановленные данные через ChartData.getChartDataWorkbook:

var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");

const spreadsheetOptions = new aspose.slides.SpreadsheetOptions();
spreadsheetOptions.setRecoverWorkbookFromChartCache(true);

const loadOptions = new aspose.slides.LoadOptions();
loadOptions.setSpreadsheetOptions(spreadsheetOptions);

const presentation = new aspose.slides.Presentation("presentation.pptx", loadOptions);
try {
    const chart = presentation.getSlides().get_Item(0).getShapes().get_Item(0);
    const recoveredWorkbook = chart.getChartData().getChartDataWorkbook();

    // Считать или изменить восстановленные данные рабочей книги здесь.
} finally {
    presentation.dispose();
}

Если внешняя рабочая книга недоступна и восстановление отключено, Aspose.Slides генерирует исключение. Включайте восстановление только в том случае, когда использование закешированных данных диаграммы является приемлемой альтернативой, поскольку кеш может не содержать изменений, внесённых во внешнюю рабочую книгу после последнего обновления презентации.

FAQ

Можно ли определить, связана ли конкретная диаграмма с внешней или встроенной рабочей книгой?

Да. У диаграммы есть тип источника данных и путь к внешней рабочей книге; если источник — внешняя рабочая книга, можно прочитать полный путь, чтобы убедиться, что используется внешний файл.

Поддерживаются ли относительные пути к внешним рабочим книгам и как они хранятся?

Да. При указании относительного пути он автоматически преобразуется в абсолютный. Это удобно для портативности проекта; однако в файле PPTX сохраняется абсолютный путь.

Можно ли использовать рабочие книги, расположенные на сетевых ресурсах/общих папках?

Да, такие рабочие книги могут использоваться как внешний источник данных. Однако прямое редактирование удалённых рабочих книг из Aspose.Slides не поддерживается — их можно только использовать в качестве источника.

Перезаписывает ли Aspose.Slides внешнюю XLSX при сохранении презентации?

Нет. Презентация хранит ссылку на внешний файл и использует её только для чтения данных. Сам внешний файл не изменяется при сохранении презентации.

Что делать, если внешний файл защищён паролем?

Aspose.Slides не принимает пароль при установке ссылки. Обычно снимают защиту заранее или подготавливают расшифрованную копию (например, с помощью Aspose.Cells) и ссылаются на неё.

Могут ли несколько диаграмм ссылаться на одну и ту же внешнюю рабочую книгу?

Да. Каждая диаграмма хранит свою собственную ссылку. Если они указывают на один и тот же файл, обновление этого файла будет отражено во всех диаграммах при следующей загрузке данных.