在 MVC Web 请求之间缓存 EPPlus 的最佳方式?

Best way to Cache EPPlus between MVC web requests?

我正在使用 EPPlus 在浏览器中显示和翻阅 Excel 文件。通过 15 行进行分页很慢,我的猜测是对于每个请求,Excel 文件都会加载到 EPPlus 中。我已经使用过滤器在控制器中缓存了操作,但我相信只缓存了 15 个结果而不是加载的 Excel 文件。

这是我现在使用的例子。它从确切的代码中剥离出来但有效。

public static byte[] GetCachedFile(string path)
    {
        ObjectCache cache = MemoryCache.Default;
        byte[] fileContents = cache[path] as byte[];

        if (fileContents == null)
        {
            CacheItemPolicy policy = new CacheItemPolicy
            {
                AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(30.0)
            };

            var filePaths = new List<string>();
            filePaths.Add(path);

            policy.ChangeMonitors.Add(new HostFileChangeMonitor(filePaths));

            // Fetch the file contents.
            using (var ms = new MemoryStream(File.ReadAllBytes(path)))
            {
                fileContents = ms.ToArray();
            }
            cache.Set(path, fileContents, policy);
        }

        return fileContents;
    }

    public async Task<ActionResult> GetXlsxObject(string filePath, int skip, int take)
    {
        var rows = new List<ExpandoObject>();
        var columnNames = new string[] {"some col name", "some other col name"};// just for example
        using (var package = new ExcelPackage(new MemoryStream(GetCachedFile(filePath))))
        {
            var workBook = package.Workbook;
            if (workBook == null) return View();
            if (workBook.Worksheets.Count <= 0) return View();
            var workSheet = workBook.Worksheets.First();
            for (var j = skip; j <= skip + take; j++)
            {
                var obj = new ExpandoObject();
                for (var i = workSheet.Dimension.Start.Column; i <= workSheet.Dimension.End.Column; i++)
                {
                    var value = string.Empty;
                    var cellValue = workSheet.Cells[j, i].Value;
                    if (cellValue != null)
                        value = cellValue.ToString().Trim();

                    ((IDictionary<string, object>)obj).Add(columnNames[i - 1], value);
                }
                rows.Add(obj);
            }
        }
        return View(rows);
    }

我会看一下数据缓存。这是缓存的简单实现。不要在生产代码中使用它。这只是一个如何让它更快的例子。

这是我用来存储数据的对象

public class ExcelResultsModel
{
    public string Path { get; set; }
    public List<ExpandoObject> Rows { get; set; }

    public ExcelResultsModel()
    {
        Rows = new List<ExpandoObject>();
    }
}

这是我创建的缓存class

public class SiteCache
{
    private ObjectCache cache;

    public SiteCache()
    {
        cache = MemoryCache.Default;
    }

    public T GetCache<T>(string key) where T : class
    {
        T data = cache[key] as T;
        return data;
    }

    public void InsertCache(string key, int seconds, object data)
    {
        CacheItemPolicy policy = new CacheItemPolicy();
        policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(seconds);
        cache.Set(key, data, policy);
    }
}

这是控制器

public ActionResult GetXlsxObject(string filePath, int skip, int take)
{
    //check to see if object is cached
    SiteCache cache = new SiteCache();
    ExcelResultsModel resultModel = cache.GetCache<ExcelResultsModel>(filePath);

    //if object is not cached. Then get and process the data then insert it in cache
    if (resultModel == null)
    {
        //Create result model
        resultModel = new ExcelResultsModel();

        var rows = new List<ExpandoObject>();
        var columnNames = new string[] { "some col name", "some other col name" };// just for example
        using (var package = new ExcelPackage())
        {
            var workBook = package.Workbook;

            if (workBook != null && workBook.Worksheets.Count > 0)
            {
                var workSheet = workBook.Worksheets.First();
                for (var j = skip; j <= skip + take; j++)
                {
                    var obj = new ExpandoObject();
                    for (var i = workSheet.Dimension.Start.Column; i <= workSheet.Dimension.End.Column; i++)
                    {
                        var value = string.Empty;
                        var cellValue = workSheet.Cells[j, i].Value;
                        if (cellValue != null)
                            value = cellValue.ToString().Trim();

                        ((IDictionary<string, object>)obj).Add(columnNames[i - 1], value);
                    }
                    rows.Add(obj);
                }

                resultModel.Path = filePath;
                resultModel.Rows = rows;
                cache.InsertCache(filePath, 300, resultModel);
            }
            else
            {
                cache.InsertCache(filePath, 300, null);
                return View();
            }
        }
    }

    return View(resultModel.Rows);
}