从 WebMethod 返回 SpreadsheetGear 工作簿流
Returning SpreadsheetGear workbook stream from WebMethod
我想提供一个 Web 服务,让我可以下载某些 Excel 工作簿。这些 Excel 工作簿是可以用数据修改的 SpreadsheetGear 对象。我不想将它们写成一个文件和 return 文件。相反,我想将它们流式传输到浏览器中,以便用户获得下载的文件。
这是我的尝试,但没有成功,来自 this guide from SpreadsheetGear's site:
[System.Web.Services.WebMethod(
Description = "Returns a stream for the excel file")]
public ActionResult downloadTemplate(string excelFileName)
{
var workbook = makeSpreadsheetGearWorkbookFrom(excelFileName);
// Save workbook to an Open XML (XLSX) workbook stream.
System.IO.Stream stream = workbook.SaveToStream(
SpreadsheetGear.FileFormat.OpenXMLWorkbook);
// Reset stream's current position back to the beginning.
stream.Seek(0, System.IO.SeekOrigin.Begin);
return new FileStreamResult(stream,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
我收到以下错误:
The web service returned the following result:
500 - Internal Server Error
System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: System.Web.Mvc.FileStreamResult cannot be serialized because it does not have a parameterless constructor.
at System.Xml.Serialization.TypeDesc.CheckSupported () [0x0001c] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.TypeScope.GetTypeDesc (System.Type type, System.Reflection.MemberInfo source, System.Boolean directReference, System.Boolean throwOnError) [0x0006a] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.TypeScope.GetTypeDesc (System.Type type) [0x00000] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.XmlSerializationWriter.CreateUnknownTypeException (System.Type type) [0x00039] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.XmlSerializationWriter.CreateUnknownTypeException (System.Object o) [0x00007] in <611e64636ff745389933c69c817b2d4a>:0
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write3_ActionResult (System.String n, System.String ns, System.Web.Mvc.ActionResult o, System.Boolean isNullable, System.Boolean needType) [0x00048] in <3fa7e61a58e74ec08df7a46ab2fb8972>:0
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write7_ActionResult (System.Object o) [0x00028] in <3fa7e61a58e74ec08df7a46ab2fb8972>:0
at Microsoft.Xml.Serialization.GeneratedAssembly.ActionResultSerializer.Serialize (System.Object objectToSerialize, System.Xml.Serialization.XmlSerializationWriter writer) [0x00000] in <3fa7e61a58e74ec08df7a46ab2fb8972>:0
at System.Xml.Serialization.XmlSerializer.Serialize (System.Xml.XmlWriter xmlWriter, System.Object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces, System.String encodingStyle, System.String id) [0x00098] in <611e64636ff745389933c69c817b2d4a>:0
StackTraceEnd
at System.Xml.Serialization.XmlSerializer.Serialize (System.Xml.XmlWriter xmlWriter, System.Object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces, System.String encodingStyle, System.String id) [0x0012f] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.XmlSerializer.Serialize (System.Xml.XmlWriter xmlWriter, System.Object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces, System.String encodingStyle) [0x00000] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.XmlSerializer.Serialize (System.Xml.XmlWriter xmlWriter, System.Object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces) [0x00000] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.XmlSerializer.Serialize (System.IO.TextWriter textWriter, System.Object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces) [0x00015] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.XmlSerializer.Serialize (System.IO.TextWriter textWriter, System.Object o) [0x00000] in <611e64636ff745389933c69c817b2d4a>:0
at System.Web.Services.Protocols.XmlReturnWriter.Write (System.Web.HttpResponse response, System.IO.Stream outputStream, System.Object returnValue) [0x00079] in <11189ae945ae429a8c10c5e8a65a097a>:0
at System.Web.Services.Protocols.HttpServerProtocol.WriteReturns (System.Object[] returnValues, System.IO.Stream outputStream) [0x0003f] in <11189ae945ae429a8c10c5e8a65a097a>:0
at System.Web.Services.Protocols.WebServiceHandler.WriteReturns (System.Object[] returnValues) [0x00051] in <11189ae945ae429a8c10c5e8a65a097a>:0
at System.Web.Services.Protocols.WebServiceHandler.Invoke () [0x000cc] in <11189ae945ae429a8c10c5e8a65a097a>:0
我该如何处理?
通过返回字节列表而不是 StreamResult 解决了问题,如下所示:
public byte[] downloadTemplate(string excelFileName)
//...
byte[] modelData = toByteArray(stream);
return modelData;
}
public byte[] toByteArray(System.IO.Stream stream)
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
stream.CopyTo(ms);
return ms.ToArray();
}
}
很容易将字节数组放入 JObject,然后放入 XML 信封。
我想提供一个 Web 服务,让我可以下载某些 Excel 工作簿。这些 Excel 工作簿是可以用数据修改的 SpreadsheetGear 对象。我不想将它们写成一个文件和 return 文件。相反,我想将它们流式传输到浏览器中,以便用户获得下载的文件。
这是我的尝试,但没有成功,来自 this guide from SpreadsheetGear's site:
[System.Web.Services.WebMethod(
Description = "Returns a stream for the excel file")]
public ActionResult downloadTemplate(string excelFileName)
{
var workbook = makeSpreadsheetGearWorkbookFrom(excelFileName);
// Save workbook to an Open XML (XLSX) workbook stream.
System.IO.Stream stream = workbook.SaveToStream(
SpreadsheetGear.FileFormat.OpenXMLWorkbook);
// Reset stream's current position back to the beginning.
stream.Seek(0, System.IO.SeekOrigin.Begin);
return new FileStreamResult(stream,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
我收到以下错误:
The web service returned the following result:
500 - Internal Server Error
System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: System.Web.Mvc.FileStreamResult cannot be serialized because it does not have a parameterless constructor.
at System.Xml.Serialization.TypeDesc.CheckSupported () [0x0001c] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.TypeScope.GetTypeDesc (System.Type type, System.Reflection.MemberInfo source, System.Boolean directReference, System.Boolean throwOnError) [0x0006a] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.TypeScope.GetTypeDesc (System.Type type) [0x00000] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.XmlSerializationWriter.CreateUnknownTypeException (System.Type type) [0x00039] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.XmlSerializationWriter.CreateUnknownTypeException (System.Object o) [0x00007] in <611e64636ff745389933c69c817b2d4a>:0
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write3_ActionResult (System.String n, System.String ns, System.Web.Mvc.ActionResult o, System.Boolean isNullable, System.Boolean needType) [0x00048] in <3fa7e61a58e74ec08df7a46ab2fb8972>:0
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write7_ActionResult (System.Object o) [0x00028] in <3fa7e61a58e74ec08df7a46ab2fb8972>:0
at Microsoft.Xml.Serialization.GeneratedAssembly.ActionResultSerializer.Serialize (System.Object objectToSerialize, System.Xml.Serialization.XmlSerializationWriter writer) [0x00000] in <3fa7e61a58e74ec08df7a46ab2fb8972>:0
at System.Xml.Serialization.XmlSerializer.Serialize (System.Xml.XmlWriter xmlWriter, System.Object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces, System.String encodingStyle, System.String id) [0x00098] in <611e64636ff745389933c69c817b2d4a>:0
StackTraceEnd
at System.Xml.Serialization.XmlSerializer.Serialize (System.Xml.XmlWriter xmlWriter, System.Object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces, System.String encodingStyle, System.String id) [0x0012f] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.XmlSerializer.Serialize (System.Xml.XmlWriter xmlWriter, System.Object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces, System.String encodingStyle) [0x00000] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.XmlSerializer.Serialize (System.Xml.XmlWriter xmlWriter, System.Object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces) [0x00000] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.XmlSerializer.Serialize (System.IO.TextWriter textWriter, System.Object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces) [0x00015] in <611e64636ff745389933c69c817b2d4a>:0
at System.Xml.Serialization.XmlSerializer.Serialize (System.IO.TextWriter textWriter, System.Object o) [0x00000] in <611e64636ff745389933c69c817b2d4a>:0
at System.Web.Services.Protocols.XmlReturnWriter.Write (System.Web.HttpResponse response, System.IO.Stream outputStream, System.Object returnValue) [0x00079] in <11189ae945ae429a8c10c5e8a65a097a>:0
at System.Web.Services.Protocols.HttpServerProtocol.WriteReturns (System.Object[] returnValues, System.IO.Stream outputStream) [0x0003f] in <11189ae945ae429a8c10c5e8a65a097a>:0
at System.Web.Services.Protocols.WebServiceHandler.WriteReturns (System.Object[] returnValues) [0x00051] in <11189ae945ae429a8c10c5e8a65a097a>:0
at System.Web.Services.Protocols.WebServiceHandler.Invoke () [0x000cc] in <11189ae945ae429a8c10c5e8a65a097a>:0
我该如何处理?
通过返回字节列表而不是 StreamResult 解决了问题,如下所示:
public byte[] downloadTemplate(string excelFileName)
//...
byte[] modelData = toByteArray(stream);
return modelData;
}
public byte[] toByteArray(System.IO.Stream stream)
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
stream.CopyTo(ms);
return ms.ToArray();
}
}
很容易将字节数组放入 JObject,然后放入 XML 信封。