Procedimientos recomendados para trabajar con la API de Excel
Artículo
En este artículo se proporcionan recomendaciones para trabajar con las API de Excel en Microsoft Graph.
Administrar sesiones de la manera más eficaz
Si tiene más de una llamada que realizar en un período de tiempo determinado, se recomienda crear una sesión y pasar el identificador de sesión con cada solicitud. Para representar la sesión en la API, utilice el encabezado workbook-session-id: {session-id}. Al hacerlo, puede usar las API de Excel de la manera más eficaz.
En el ejemplo siguiente se muestra cómo agregar un nuevo número a una tabla y, a continuación, buscar un registro en un libro mediante este enfoque.
POST https://graph.microsoft.com/v1.0/me/drive/items/{id}/workbook/createSession
Content-type: application/json
{
"persistChanges": true
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Drives.Item.Items.Item.Workbook.CreateSession;
var requestBody = new CreateSessionPostRequestBody
{
PersistChanges = true,
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Drives["{drive-id}"].Items["{driveItem-id}"].Workbook.CreateSession.PostAsync(requestBody);
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphdrives "github.com/microsoftgraph/msgraph-sdk-go/drives"
//other-imports
)
requestBody := graphdrives.NewCreateSessionPostRequestBody()
persistChanges := true
requestBody.SetPersistChanges(&persistChanges)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
createSession, err := graphClient.Drives().ByDriveId("drive-id").Items().ByDriveItemId("driveItem-id").Workbook().CreateSession().Post(context.Background(), requestBody, nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
com.microsoft.graph.drives.item.items.item.workbook.createsession.CreateSessionPostRequestBody createSessionPostRequestBody = new com.microsoft.graph.drives.item.items.item.workbook.createsession.CreateSessionPostRequestBody();
createSessionPostRequestBody.setPersistChanges(true);
var result = graphClient.drives().byDriveId("{drive-id}").items().byDriveItemId("{driveItem-id}").workbook().createSession().post(createSessionPostRequestBody);
<?php
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Graph\Generated\Drives\Item\Items\Item\Workbook\CreateSession\CreateSessionPostRequestBody;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new CreateSessionPostRequestBody();
$requestBody->setPersistChanges(true);
$result = $graphServiceClient->drives()->byDriveId('drive-id')->items()->byDriveItemId('driveItem-id')->workbook()->createSession()->post($requestBody)->wait();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.drives.item.items.item.workbook.create_session.create_session_post_request_body import CreateSessionPostRequestBody
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = CreateSessionPostRequestBody(
persist_changes = True,
)
result = await graph_client.drives.by_drive_id('drive-id').items.by_drive_item_id('driveItem-id').workbook.create_session.post(request_body)
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Drives.Item.Items.Item.Workbook.Functions.Vlookup;
using Microsoft.Kiota.Abstractions.Serialization;
var requestBody = new VlookupPostRequestBody
{
LookupValue = new UntypedString("pear"),
TableArray = new UntypedObject(new Dictionary<string, UntypedNode>
{
{
"Address", new UntypedString("Sheet1!B2:C7")
},
}),
ColIndexNum = new UntypedDouble(2),
RangeLookup = new UntypedBoolean(false),
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Drives["{drive-id}"].Items["{driveItem-id}"].Workbook.Functions.Vlookup.PostAsync(requestBody, (requestConfiguration) =>
{
requestConfiguration.Headers.Add("workbook-session-id", "{session-id}");
});
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
com.microsoft.graph.drives.item.items.item.workbook.functions.vlookup.VlookupPostRequestBody vlookupPostRequestBody = new com.microsoft.graph.drives.item.items.item.workbook.functions.vlookup.VlookupPostRequestBody();
vlookupPostRequestBody.setLookupValue("pear");
UntypedNode tableArray = new UntypedNode();
tableArray.setAddress("Sheet1!B2:C7");
vlookupPostRequestBody.setTableArray(tableArray);
vlookupPostRequestBody.setColIndexNum(2d);
vlookupPostRequestBody.setRangeLookup(false);
var result = graphClient.drives().byDriveId("{drive-id}").items().byDriveItemId("{driveItem-id}").workbook().functions().vlookup().post(vlookupPostRequestBody, requestConfiguration -> {
requestConfiguration.headers.add("workbook-session-id", "{session-id}");
});
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.drives.item.items.item.workbook.functions.vlookup.vlookup_request_builder import VlookupRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
from msgraph.generated.drives.item.items.item.workbook.functions.vlookup.vlookup_post_request_body import VlookupPostRequestBody
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = VlookupPostRequestBody(
lookup_value = "pear",
table_array = UntypedNode(
address = "Sheet1!B2:C7",
),
col_index_num = 2,
range_lookup = False,
)
request_configuration = RequestConfiguration()
request_configuration.headers.add("workbook-session-id", "{session-id}")
result = await graph_client.drives.by_drive_id('drive-id').items.by_drive_item_id('driveItem-id').workbook.functions.vlookup.post(request_body, request_configuration = request_configuration)
POST https://graph.microsoft.com/v1.0/me/drive/items/{id}/workbook/closeSession
Content-type: application/json
workbook-session-id: {session-id}
{
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Drives.Item.Items.Item.Workbook.CloseSession;
var requestBody = new CloseSessionPostRequestBody
{
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
await graphClient.Drives["{drive-id}"].Items["{driveItem-id}"].Workbook.CloseSession.PostAsync(requestBody, (requestConfiguration) =>
{
requestConfiguration.Headers.Add("workbook-session-id", "{session-id}");
});
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
abstractions "github.com/microsoft/kiota-abstractions-go"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphdrives "github.com/microsoftgraph/msgraph-sdk-go/drives"
//other-imports
)
headers := abstractions.NewRequestHeaders()
headers.Add("workbook-session-id", "{session-id}")
configuration := &graphdrives.DriveItemItemItemWorkbookCloseSessionRequestBuilderPostRequestConfiguration{
Headers: headers,
}
requestBody := graphdrives.NewCloseSessionPostRequestBody()
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
graphClient.Drives().ByDriveId("drive-id").Items().ByDriveItemId("driveItem-id").Workbook().CloseSession().Post(context.Background(), requestBody, configuration)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
com.microsoft.graph.drives.item.items.item.workbook.closesession.CloseSessionPostRequestBody closeSessionPostRequestBody = new com.microsoft.graph.drives.item.items.item.workbook.closesession.CloseSessionPostRequestBody();
graphClient.drives().byDriveId("{drive-id}").items().byDriveItemId("{driveItem-id}").workbook().closeSession().post(closeSessionPostRequestBody, requestConfiguration -> {
requestConfiguration.headers.add("workbook-session-id", "{session-id}");
});
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.drives.item.items.item.workbook.close_session.close_session_request_builder import CloseSessionRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
from msgraph.generated.drives.item.items.item.workbook.close_session.close_session_post_request_body import CloseSessionPostRequestBody
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = CloseSessionPostRequestBody(
)
request_configuration = RequestConfiguration()
request_configuration.headers.add("workbook-session-id", "{session-id}")
await graph_client.drives.by_drive_id('drive-id').items.by_drive_item_id('driveItem-id').workbook.close_session.post(request_body, request_configuration = request_configuration)
Trabajar con API que tardan mucho tiempo en completarse
Es posible que observe que algunas operaciones tardan un tiempo indeterminado en completarse; por ejemplo, abrir un libro grande. Es fácil alcanzar el tiempo de espera mientras se espera la respuesta a estas solicitudes. Para resolver este problema, se proporciona el patrón de operación de ejecución prolongada. Cuando se usa este patrón, no es necesario preocuparse por el tiempo de espera de la solicitud.
Actualmente, la API de Excel de creación de sesión en Microsoft Graph tiene habilitado el patrón de operación de ejecución prolongada. Este patrón implica los pasos siguientes:
Agregue un Prefer: respond-async encabezado a la solicitud para indicar que se trata de una operación de larga duración al crear una sesión.
Una operación de ejecución prolongada devuelve una 202 Accepted respuesta junto con un encabezado Location para recuperar el estado de la operación. Si la creación de la sesión se completa en varios segundos, devuelve una respuesta de sesión de creación regular en lugar de usar el patrón de operación de ejecución prolongada.
Con la 202 Accepted respuesta, puede recuperar el estado de la operación en la ubicación especificada. Los valores de estado de la operación son notStarted, running, succeededy failed.
Una vez completada la operación, puede obtener el resultado de la creación de la sesión a través de la dirección URL especificada en la respuesta correcta.
En el ejemplo siguiente se crea una sesión con el patrón de operación de ejecución prolongada.
POST https://graph.microsoft.com/v1.0/me/drive/items/{drive-item-id}/workbook/createSession
Prefer: respond-async
Content-type: application/json
{
"persistChanges": true
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Drives.Item.Items.Item.Workbook.CreateSession;
var requestBody = new CreateSessionPostRequestBody
{
PersistChanges = true,
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Drives["{drive-id}"].Items["{driveItem-id}"].Workbook.CreateSession.PostAsync(requestBody, (requestConfiguration) =>
{
requestConfiguration.Headers.Add("Prefer", "respond-async");
});
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
abstractions "github.com/microsoft/kiota-abstractions-go"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphdrives "github.com/microsoftgraph/msgraph-sdk-go/drives"
//other-imports
)
headers := abstractions.NewRequestHeaders()
headers.Add("Prefer", "respond-async")
configuration := &graphdrives.DriveItemItemItemWorkbookCreateSessionRequestBuilderPostRequestConfiguration{
Headers: headers,
}
requestBody := graphdrives.NewCreateSessionPostRequestBody()
persistChanges := true
requestBody.SetPersistChanges(&persistChanges)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
createSession, err := graphClient.Drives().ByDriveId("drive-id").Items().ByDriveItemId("driveItem-id").Workbook().CreateSession().Post(context.Background(), requestBody, configuration)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
com.microsoft.graph.drives.item.items.item.workbook.createsession.CreateSessionPostRequestBody createSessionPostRequestBody = new com.microsoft.graph.drives.item.items.item.workbook.createsession.CreateSessionPostRequestBody();
createSessionPostRequestBody.setPersistChanges(true);
var result = graphClient.drives().byDriveId("{drive-id}").items().byDriveItemId("{driveItem-id}").workbook().createSession().post(createSessionPostRequestBody, requestConfiguration -> {
requestConfiguration.headers.add("Prefer", "respond-async");
});
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.drives.item.items.item.workbook.create_session.create_session_request_builder import CreateSessionRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
from msgraph.generated.drives.item.items.item.workbook.create_session.create_session_post_request_body import CreateSessionPostRequestBody
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = CreateSessionPostRequestBody(
persist_changes = True,
)
request_configuration = RequestConfiguration()
request_configuration.headers.add("Prefer", "respond-async")
result = await graph_client.drives.by_drive_id('drive-id').items.by_drive_item_id('driveItem-id').workbook.create_session.post(request_body, request_configuration = request_configuration)
En algunos casos, si la creación se realiza correctamente en cuestión de segundos, no escribirá el patrón de operación de ejecución prolongada; en su lugar, devuelve como una sesión de creación normal y la solicitud correcta devolverá una 201 Created respuesta.
En el ejemplo siguiente se muestra la respuesta cuando se produce un error en la solicitud.
Nota: Se puede acortar el objeto de respuesta que se muestra aquí para mejorar la legibilidad.
HTTP/1.1 500 Internal Server Error
Content-type: application/json
{
"error":{
"code": "internalServerError",
"message": "An internal server error occurred while processing the request.",
"innerError": {
"code": "internalServerErrorUncategorized",
"message": "An unspecified error has occurred.",
"innerError": {
"code": "GenericFileOpenError",
"message": "The workbook cannot be opened."
}
}
}
}
Estado de sondeo de la sesión de creación de ejecución prolongada
Con el patrón de operación de ejecución prolongada, puede obtener el estado de creación en la ubicación especificada mediante la siguiente solicitud. El intervalo sugerido para sondear el estado es de aproximadamente 30 segundos. El intervalo máximo no debe ser superior a 4 minutos.
Solicitud
GET https://graph.microsoft.com/v1.0/me/drive/items/{drive-item-id}/workbook/operations/{operation-id}
{
}
Respuesta
A continuación se muestra la respuesta cuando la operación tiene un estado de running.
Adquirir información de sesión depende de la solicitud inicial. No es necesario adquirir el resultado si la solicitud inicial no devuelve un cuerpo de respuesta.
Reducción de errores de limitación
Las API de Excel en Microsoft Graph afectan al uso de recursos de varios servicios de dependencia. El impacto puede variar entre distintas solicitudes: por ejemplo, puede esperar que actualizar una cadena corta en una sola celda de un libro pequeño consuma menos recursos que agregar una tabla grande con fórmulas complejas a un libro grande.
Incluso con la misma API, los parámetros y los libros de destino pueden introducir diferencias significativas. Por lo tanto, la limitación de la API de Excel no se define con números de límite simples y universales, ya que darían lugar a límites más restrictivos. Los siguientes procedimientos recomendados le ayudarán a completar las tareas más rápidamente con menos errores de limitación.
encabezado Retry-After
En muchos casos, una respuesta de limitación incluye un Retry-After encabezado. Respetar el valor del encabezado y retrasar solicitudes similares ayudaría al cliente a recuperarse de la limitación. Para obtener más información sobre cómo controlar las respuestas de error de las API de Excel en Microsoft Graph, vea Control de errores para las API de Excel en Microsoft Graph.
Limitación y simultaneidad
Otro factor relacionado con la limitación es la simultaneidad de solicitudes. No se recomienda aumentar la simultaneidad al usar las API de Excel (por ejemplo, paralelizar las solicitudes con el mismo libro), especialmente para las solicitudes de escritura. En su lugar, a menos que haya una preocupación específica, como una sobrecarga de red significativa en comparación con un tiempo de ejecución de solicitud muy corto, se recomienda el uso secuencial en el caso más común: para cada libro, solo envíe la siguiente solicitud después de recibir una respuesta correcta a la solicitud actual.
Las solicitudes de escritura simultáneas al mismo libro no se suelen ejecutar en paralelo (aunque en algunos casos lo hacen); en su lugar, suelen ser la causa de la limitación, el tiempo de espera (cuando las solicitudes se ponen en cola en los servidores), el conflicto de combinación (cuando hay sesiones simultáneas implicadas) y otros tipos de errores. También complican el control de errores; por ejemplo, cuando recibe una respuesta de error, no hay ninguna manera de confirmar el estado de otras solicitudes pendientes, lo que dificulta determinar o recuperar el estado del libro.