I have a .NET Core 2.2 API that I need to populate an XLSX file with data and an image. I'm using Syncfusion Xlsio 17.4.0.5 to do this. The file is populating great with the exception of the image. The image is available at a url so I need to download it from the url and insert it into the file. Here's my current attempt at doing this:
HttpClient client = new HttpClient();
using (Stream stream = await client.GetStreamAsync(imageUrl))
{
worksheet.Pictures.AddPicture(1, 1, stream);
}
When I run this, I get the following error on the AddPicture line:
{System.ArgumentException: Stream
at Syncfusion.Drawing.Image..ctor(Stream stream)
at Syncfusion.XlsIO.Implementation.Collections.PicturesCollection.AddPicture(Int32 topRow, Int32 leftColumn, Stream stream, ExcelImageFormat imageFormat)
at MyProject.App.Services.LadingService.PopulateForm(IWorksheet worksheet, Lading lading) in C:\Users\jlewi\Source\GIT\my-project-backend\src\MyProject.App\Services\LadingService.cs:line 94
at MyProject.App.Services.LadingService.GetLadingExport(String ladingId) in C:\Users\jlewi\Source\GIT\my-project-backend\src\MyProject.App\Services\LadingService.cs:line 58
at MyProject.Api.Controllers.LadingController.ExportLading(String id) in C:\Users\jlewi\Source\GIT\my-project-backend\src\MyProject.Api\Controllers\LadingController.cs:line 147
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
at MyProject.Api.Middleware.UserBlockedMiddleware.InvokeAsync(HttpContext context, IUserRepository userRepository) in C:\Users\jlewi\Source\GIT\my-project-backend\src\MyProject.Api\Middleware\UserBlockedMiddleware.cs:line 72
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at AspNetCoreRateLimit.RateLimitMiddleware`1.Invoke(HttpContext context)
at AspNetCoreRateLimit.RateLimitMiddleware`1.Invoke(HttpContext context)
at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events) in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\src\Hosting\IdentityServerMiddleware.cs:line 72
at IdentityServer4.Hosting.MutualTlsTokenEndpointMiddleware.Invoke(HttpContext context, IAuthenticationSchemeProvider schemes) in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\src\Hosting\MtlsTokenEndpointMiddleware.cs:line 60
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context) in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\src\Hosting\BaseUrlMiddleware.cs:line 36
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at VOGBackend.Core.Middleware.ApiExceptionHandlerMiddleware.InvokeAsync(HttpContext context, ILogger`1 logger, IHostingEnvironment hostingEnvironment) in C:\Users\jlewi\Source\GIT\sharedlibrary.core\src\Middleware\ApiExceptionHandlerMiddleware.cs:line 36}
I've tried it with other image urls and none work. Any thoughts?
UPDATE Okay, the following works but feels a little hacky. Maybe AddPicture doesn't like working from pure Stream objects?
HttpClient client = new HttpClient();
using (Stream stream = await client.GetStreamAsync(url))
{
using (MemoryStream memStream = new MemoryStream())
{
stream.CopyTo(memStream);
var shape = worksheet.Pictures.AddPicture(1, 1, memStream);
}
}
Syncfusion XlsIO do not have support to read HttpConnection.ContentLengthReadStream in AddPicture method, in ASP.NET Core platform.
So, we request you to copy it to MemoryStream as mentioned by you, to overcome the exception.