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

时间:2015-09-23 18:14:35

标签: asp.net-mvc caching epplus

我使用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);
    }

1 个答案:

答案 0 :(得分:1)

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

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

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

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

这是我创建的缓存类

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);
}