我有这条线:
GlobalConfiguration.Configuration.Formatters.Add(New ExcelMediaTypeFormatter(Of Classification)(Function(t) New ExcelRow(ExcelCell.Map(t.ChemicalAbstractService), ExcelCell.Map(t.Substance), ExcelCell.Map(t.Columns("Classifidcation")), ExcelCell.Map(t.Columns("Classification"))), Function(format) "excel"))
它工作正常,并从我的 web api 创建一个 excelfile。
我有几个继承这个分类类的子类,我想为每个子类制作一个媒体格式化程序,以获取 excelformatter 中的特定列。问题是,如果我这样做:
GlobalConfiguration.Configuration.Formatters.Add(New ExcelMediaTypeFormatter(Of CustomClassification)(Function(t) New ExcelRow(ExcelCell.Map(t.ChemicalAbstractService), ExcelCell.Map(t.Substance), ExcelCell.Map(t.Columns("Classifidcation")), ExcelCell.Map(t.Columns("Classification"))), Function(format) "excel"))
然后它根本不起作用。它只是从标准格式化程序生成 xml。当 web api 返回一个
IQueryable(Of Classification)
格式化程序:
public class ExcelMediaTypeFormatter<T> : BufferedMediaTypeFormatter
{
private const string ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
private readonly Func<T, ExcelRow> builder;
public ExcelMediaTypeFormatter(Func<T, ExcelRow> value)
{
builder = value;
SupportedMediaTypes.Add(new MediaTypeHeaderValue(ContentType));
}
public ExcelMediaTypeFormatter(Func<T, ExcelRow> value, params Func<object, string>[] type)
: this(value)
{
foreach (var mediaTypeMapping in type) {
this.MediaTypeMappings.Add(Map(mediaTypeMapping));
}
}
public override bool CanWriteType(Type type)
{
return type == typeof(IQueryable<T>) || type == typeof(T);
}
public override bool CanReadType(Type type)
{
return false;
}
public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
{
using (Stream ms = new MemoryStream()) {
using (var book = new ClosedXML.Excel.XLWorkbook()) {
var sheet = book.Worksheets.Add("sample");
ICollection<T> rows = type == typeof(IQueryable<T>) ? ((IQueryable<T>)value).ToList() : new List<T>() { (T)value };
for (var r = 0; r < rows.Count; r++) {
var result = builder((T)rows.ElementAt(r));
for (var c = 0; c < result.Count(); c++) {
if (result.ElementAt(c) != null)
sheet.Cell(r + 2, c + 1).Value = result.ElementAt(c).Value.ToString();
}
}
sheet.Columns().AdjustToContents();
book.SaveAs(ms);
byte[] buffer = new byte[ms.Length];
ms.Position = 0;
ms.Read(buffer, 0, buffer.Length);
writeStream.Write(buffer, 0, buffer.Length);
}
}
}