ExcelReport第二篇:ExcelReport源码解析

 

导航

目   录:基于NPOI的报表引擎——ExcelReport

上一篇:使用ExcelReport导出Excel

下一篇:扩展元素格式化器

概述

针对上一篇随笔收到的反馈,在展开对ExcelReport源码解析之前,我认为把编写该组件时的想法分享给大家是有必要的。

编写该组件时,思考如下:

1)要实现样式、格式与数据的彻底分离。

为什么要将样式、格式与数据分离呢?恩,你不妨想一想在生成报表时,那些是变的而那些又是不变的。我的结论是:变的是数据。

有了这个想法,很自然的想到用模板去承载不变的部分(常量内容的样式、格式、数据及变量内容的样式、格式),在程序中控制变的部分(变量内容的数据)。

这里以上一篇中的例子标识:

变量内容已使用粉红色边框标出,其余为常量内容。好了,相信“内容的数据”大家都知道那个是那个的。下面截图,内容的样式和格式。

现在我们回到上篇中使用的模板,相信你应该知道它承载那些东西了。

啰嗦了这么多,总结一下样式、格式与数据分离的好处:它让我们编写程序时关注更少(只需关心“变量内容的数据”)。

2)关注“变量内容的数据”填充到模板的最小单元(我们把这些称之为元素格式化器),然后利用合成模式(Composite)搞定整个文档的数据填充。

为什么要抽象一个“元素格式化器”的概念呢?我们看数据源,我们有可能要将某个类型的数据填充到某个单元格、也可能将一个集合填充到多行、有可能将一张图片填充到某个位置、也有可能就将某个字符串合并到某个单元格的内容中......如此种种。那么它们有什么共同点呢?它们都是填充“变量内容的数据”到模板的。

3)外部调用,统一从一个处理入口处理。

源码解析

有了上面的背景,这张UML想必不难理解了。

当然,如果你还是觉得复杂, 没关系。我会先介绍一下这里面几个重点关系。

1)从Export类开始吧!

这是一个静态类,非常简单。只有两个静态方法:ExportToLocal()、ExportToWeb()分别将生成的文件导出到本地和Web。这多半是废话了,下面是重点:

这便引出了SheetFormatterContainer类,SheetFormatterContainer类是何许也?

  • SheetFormatterContainer是一个存储“格式化一个Sheet用到的元素格式化器集合”的容器。

说到这,顺便说下:ElementFormatter类和SheetFormatterContext类。

  • ElementFormatter:元素格式化器。
  • SheetFormatterContext:Sheet格式化上下文。

回到Export:

  1. public static byte[] ExportToBuffer(string templateFile, params SheetFormatterContainer[] containers)
  1. {
  1. var workbook = LoadTemplateWorkbook(templateFile);
  1. foreach (var container in containers)
  1. {
  1. var sheet = workbook.GetSheet(container.SheetName);
  1. var context = new SheetFormatterContext(sheet, container.Formatters);
  1. context.Format();
  1. }
  1. return workbook.SaveToBuffer();
  1. }

如上代码,在执行导出的过程中,将每一个SheetFormatterContainer对象转换成了SheetFormatterContext对象。然后SheetFormatterContext对象调用自身的Format()方法格式化Sheet。

  1. public void Format()
  1. {
  1. if (null == Sheet || null == Formatters)
  1. {
  1. return;
  1. }
  1. foreach (var formatter in Formatters)
  1. {
  1. formatter.Format(this);
  1. }
  1. }

Formatters就是从SheetFormatterContainer传过来的“元素格式化器”集合。

抽象的“元素格式化器”:

至此,ExcelReport组件的核心部分已经介绍完成了,下面附上代码(如下代码仅供参考,了解ExcelReport组件最新动态,请到GitHub下载最新源码)。

2)附--(ExcelReport1.0源码)

SheetFormatterContainer.cs

  1. /*
  1. 类:SheetFormatterContainer
  1. 描述:Sheet中元素的格式化器集合
  1. 人:韩兆新 日期:20150117
  1. 修改记录:
  1.  
  1. */
  1.  
  1. using System.Collections.Generic;
  1.  
  1. namespace ExcelReport
  1. {
  1. public class SheetFormatterContainer
  1. {
  1. #region 成员字段及属性
  1.  
  1. private string sheetName;
  1.  
  1. public string SheetName
  1. {
  1. get { return sheetName; }
  1. }
  1.  
  1. private IEnumerable<ElementFormatter> formatters;
  1.  
  1. public IEnumerable<ElementFormatter> Formatters
  1. {
  1. get { return formatters; }
  1. }
  1.  
  1. #endregion 成员字段及属性
  1.  
  1. #region 构造函数
  1.  
  1. public SheetFormatterContainer(string sheetName, IEnumerable<ElementFormatter> formatters)
  1. {
  1. this.sheetName = sheetName;
  1. this.formatters = formatters;
  1. }
  1.  
  1. #endregion 构造函数
  1. }
  1. }

SheetFormatterContext.cs

  1. /*
  1. 类:SheetFormatterContext
  1. 描述:Sheet格式化的上下文
  1. 人:韩兆新 日期:20150117
  1. 修改记录:
  1.  
  1. */
  1.  
  1. using System.Collections.Generic;
  1. using NPOI.SS.UserModel;
  1.  
  1. namespace ExcelReport
  1. {
  1. public class SheetFormatterContext
  1. {
  1. #region 成员字段及属性
  1.  
  1. private int _increaseRowsCount = 0;
  1.  
  1. public ISheet Sheet { get; set; }
  1.  
  1. public IEnumerable<ElementFormatter> Formatters { get; set; }
  1.  
  1. #endregion 成员字段及属性
  1.  
  1. #region 构造函数
  1.  
  1. public SheetFormatterContext()
  1. {
  1. }
  1.  
  1. public SheetFormatterContext(ISheet sheet, IEnumerable<ElementFormatter> formatters)
  1. {
  1. this.Sheet = sheet;
  1. this.Formatters = formatters;
  1. }
  1.  
  1. #endregion 构造函数
  1.  
  1. #region 获取指定行当前行标
  1.  
  1. /// <summary>
  1. /// 获取指定行当前行标
  1. /// </summary>
  1. /// <param name="rowIndexInTemplate">指定行在模板中的行标</param>
  1. /// <returns>当前行标</returns>
  1. public int GetCurrentRowIndex(int rowIndexInTemplate)
  1. {
  1. return rowIndexInTemplate + _increaseRowsCount;
  1. }
  1.  
  1. #endregion 获取指定行当前行标
  1.  
  1. #region 在指定行后插入一行(并将指定行作为模板复制样式)
  1.  
  1. /// <summary>
  1. /// 在指定行后插入一行(并将指定行作为模板复制样式)
  1. /// </summary>
  1. /// <param name="templateRowIndex">模板行在模板中的行标</param>
  1. public void InsertEmptyRow(int templateRowIndex)
  1. {
  1. var templateRow = Sheet.GetRow(GetCurrentRowIndex(templateRowIndex));
  1. var insertRowIndex = GetCurrentRowIndex(templateRowIndex + 1);
  1. if (insertRowIndex < Sheet.LastRowNum)
  1. {
  1. Sheet.ShiftRows(insertRowIndex, Sheet.LastRowNum, 1, true, false);
  1. }
  1. var newRow = Sheet.CreateRow(GetCurrentRowIndex(templateRowIndex + 1));
  1. _increaseRowsCount++;
  1. foreach (var cell in templateRow.Cells)
  1. {
  1. newRow.CreateCell(cell.ColumnIndex).CellStyle = cell.CellStyle;
  1. }
  1. }
  1.  
  1. #endregion 在指定行后插入一行(并将指定行作为模板复制样式)
  1.  
  1. #region 清除指定行单元格内容
  1.  
  1. /// <summary>
  1. /// 清除指定行单元格内容
  1. /// </summary>
  1. /// <param name="rowIndex">指定行在模板中的行标</param>
  1. public void ClearRowContent(int rowIndex)
  1. {
  1. var row = Sheet.GetRow(GetCurrentRowIndex(rowIndex));
  1. foreach (var cell in row.Cells)
  1. {
  1. cell.SetCellValue(string.Empty);
  1. }
  1. }
  1.  
  1. #endregion 清除指定行单元格内容
  1.  
  1. #region 删除指定行
  1.  
  1. /// <summary>
  1. /// 删除指定行
  1. /// </summary>
  1. /// <param name="rowIndex">指定行在模板中的行标</param>
  1. public void RemoveRow(int rowIndex)
  1. {
  1. var row = Sheet.GetRow(GetCurrentRowIndex(rowIndex));
  1. Sheet.RemoveRow(row);
  1. }
  1.  
  1. #endregion 删除指定行
  1.  
  1. #region 格式化Sheet
  1.  
  1. /// <summary>
  1. /// 格式化Sheet
  1. /// </summary>
  1. public void Format()
  1. {
  1. if (null == Sheet || null == Formatters)
  1. {
  1. return;
  1. }
  1. foreach (var formatter in Formatters)
  1. {
  1. formatter.Format(this);
  1. }
  1. }
  1.  
  1. #endregion 格式化Sheet
  1. }
  1. }

ElementFormatter.cs

  1. /*
  1. 类:ElementFormatter
  1. 描述:(元素)格式化器(抽象)
  1. 人:韩兆新 日期:20150117
  1. 修改记录:
  1.  
  1. */
  1.  
  1. using System;
  1. using NPOI.SS.UserModel;
  1.  
  1. namespace ExcelReport
  1. {
  1. public abstract class ElementFormatter
  1. {
  1. #region 设置单元格值
  1.  
  1. protected virtual void SetCellValue(ICell cell, object value)
  1. {
  1. if (null == cell)
  1. {
  1. return;
  1. }
  1. if (null == value)
  1. {
  1. cell.SetCellValue(string.Empty);
  1. }
  1. else
  1. {
  1. var valueTypeCode = Type.GetTypeCode(value.GetType());
  1.  
  1. switch (valueTypeCode)
  1. {
  1. case TypeCode.String: //字符串类型
  1. cell.SetCellValue(Convert.ToString(value));
  1. break;
  1.  
  1. case TypeCode.DateTime: //日期类型
  1. cell.SetCellValue(Convert.ToDateTime(value));
  1. break;
  1.  
  1. case TypeCode.Boolean: //布尔型
  1. cell.SetCellValue(Convert.ToBoolean(value));
  1. break;
  1.  
  1. case TypeCode.Int16: //整型
  1. case TypeCode.Int32:
  1. case TypeCode.Int64:
  1. case TypeCode.Byte:
  1. case TypeCode.Single: //浮点型
  1. case TypeCode.Double:
  1. case TypeCode.UInt16: //无符号整型
  1. case TypeCode.UInt32:
  1. case TypeCode.UInt64:
  1. cell.SetCellValue(Convert.ToDouble(value));
  1. break;
  1.  
  1. default:
  1. cell.SetCellValue(string.Empty);
  1. break;
  1. }
  1. }
  1. }
  1.  
  1. #endregion 设置单元格值
  1.  
  1. #region 格式化操作
  1.  
  1. public abstract void Format(SheetFormatterContext context);
  1.  
  1. #endregion 格式化操作
  1. }
  1. }

CellFormatter.cs

  1. /*
  1. 类:CellFormatter
  1. 描述:单元格(元素)格式化器
  1. 人:韩兆新 日期:20150117
  1. 修改记录:
  1.  
  1. */
  1.  
  1. using System.Drawing;
  1.  
  1. namespace ExcelReport
  1. {
  1. public class CellFormatter : ElementFormatter
  1. {
  1. #region 成员字段及属性
  1.  
  1. private Point _cellPoint;
  1. private object _value;
  1.  
  1. #endregion 成员字段及属性
  1.  
  1. #region 构造函数
  1.  
  1. public CellFormatter(Point cellPoint, object value)
  1. {
  1. _cellPoint = cellPoint;
  1. _value = value;
  1. }
  1.  
  1. public CellFormatter(int rowIndex, int columnIndex, object value)
  1. {
  1. _cellPoint = new Point(rowIndex, columnIndex);
  1. _value = value;
  1. }
  1.  
  1. #endregion 构造函数
  1.  
  1. #region 格式化操作
  1.  
  1. public override void Format(SheetFormatterContext context)
  1. {
  1. var rowIndex = context.GetCurrentRowIndex(_cellPoint.X);
  1. var row = context.Sheet.GetRow(rowIndex);
  1. if (null == row)
  1. {
  1. row = context.Sheet.CreateRow(rowIndex);
  1. }
  1. var cell = row.GetCell(_cellPoint.Y);
  1. if (null == cell)
  1. {
  1. cell = row.CreateCell(_cellPoint.Y);
  1. }
  1. SetCellValue(cell, _value);
  1. }
  1.  
  1. #endregion 格式化操作
  1. }
  1. }

TableFormatter.cs

  1. /*
  1. 类:TableFormatter
  1. 描述:表格(元素)格式化器
  1. 人:韩兆新 日期:20150117
  1. 修改记录:
  1.  
  1. */
  1.  
  1. using System;
  1. using System.Collections.Generic;
  1.  
  1. namespace ExcelReport
  1. {
  1. public class TableFormatter<TSource> : ElementFormatter
  1. {
  1. #region 成员字段
  1.  
  1. private int _templateRowIndex;
  1. private IEnumerable<TSource> _dataSource;
  1. private List<TableColumnInfo<TSource>> _columnInfoList;
  1.  
  1. #endregion 成员字段
  1.  
  1. #region 构造函数
  1.  
  1. public TableFormatter(int templateRowIndex, IEnumerable<TSource> dataSource, params TableColumnInfo<TSource>[] columnInfos)
  1. {
  1. _templateRowIndex = templateRowIndex;
  1. _dataSource = dataSource;
  1. _columnInfoList = new List<TableColumnInfo<TSource>>();
  1. if (null != columnInfos && columnInfos.Length > 0)
  1. {
  1. _columnInfoList.AddRange(columnInfos);
  1. }
  1. }
  1.  
  1. #endregion 构造函数
  1.  
  1. #region 格式化操作
  1.  
  1. public override void Format(SheetFormatterContext context)
  1. {
  1. context.ClearRowContent(_templateRowIndex); //清除模板行单元格内容
  1. if (null == _columnInfoList || _columnInfoList.Count <= 0 || null == _dataSource)
  1. {
  1. return;
  1. }
  1. foreach (TSource rowSource in _dataSource)
  1. {
  1. var row = context.Sheet.GetRow(context.GetCurrentRowIndex(_templateRowIndex));
  1. foreach (TableColumnInfo<TSource> colInfo in _columnInfoList)
  1. {
  1. var cell = row.GetCell(colInfo.ColumnIndex);
  1. SetCellValue(cell, colInfo.DgSetValue(rowSource));
  1. }
  1. context.InsertEmptyRow(_templateRowIndex); //追加空行
  1. }
  1. context.RemoveRow(_templateRowIndex); //删除空行
  1. }
  1.  
  1. #endregion 格式化操作
  1.  
  1. #region 添加列信息
  1.  
  1. public void AddColumnInfo(TableColumnInfo<TSource> columnInfo)
  1. {
  1. _columnInfoList.Add(columnInfo);
  1. }
  1.  
  1. public void AddColumnInfo(int columnIndex, Func<TSource, object> dgSetValue)
  1. {
  1. _columnInfoList.Add(new TableColumnInfo<TSource>(columnIndex, dgSetValue));
  1. }
  1.  
  1. #endregion 添加列信息
  1. }
  1. }

ExportHelper.cs

  1. /*
  1. 类:ExportHelper
  1. 描述:导出助手类
  1. 人:韩兆新 日期:20150117
  1. 修改记录:
  1.  
  1. */
  1.  
  1. using System.IO;
  1. using NPOI.SS.UserModel;
  1.  
  1. namespace ExcelReport
  1. {
  1. internal static class ExportHelper
  1. {
  1. #region 加载模板,获取IWorkbook对象
  1.  
  1. private static IWorkbook LoadTemplateWorkbook(string templateFile)
  1. {
  1. using (var fileStream = new FileStream(templateFile, FileMode.Open, FileAccess.Read)) //读入excel模板
  1. {
  1. return WorkbookFactory.Create(fileStream);
  1. }
  1. }
  1.  
  1. #endregion 加载模板,获取IWorkbook对象
  1.  
  1. #region 将IWorkBook对象转换成二进制文件流
  1.  
  1. private static byte[] SaveToBuffer(this IWorkbook workbook)
  1. {
  1. using (var ms = new MemoryStream())
  1. {
  1. workbook.Write(ms);
  1. ms.Flush();
  1. ms.Position = 0;
  1. return ms.GetBuffer();
  1. }
  1. }
  1.  
  1. #endregion 将IWorkBook对象转换成二进制文件流
  1.  
  1. #region 导出格式化处理后的文件到二进制文件流
  1.  
  1. public static byte[] ExportToBuffer(string templateFile, params SheetFormatterContainer[] containers)
  1. {
  1. var workbook = LoadTemplateWorkbook(templateFile);
  1. foreach (var container in containers)
  1. {
  1. var sheet = workbook.GetSheet(container.SheetName);
  1. var context = new SheetFormatterContext(sheet, container.Formatters);
  1. context.Format();
  1. }
  1. return workbook.SaveToBuffer();
  1. }
  1.  
  1. #endregion 导出格式化处理后的文件到二进制文件流
  1. }
  1. }

Export.cs

  1. /*
  1. 类:Export
  1. 描述:导出
  1. 人:韩兆新 日期:20150117
  1. 修改记录:
  1.  
  1. */
  1.  
  1. using System;
  1. using System.IO;
  1. using System.Web;
  1.  
  1. namespace ExcelReport
  1. {
  1. public static class Export
  1. {
  1. #region 导出到本地
  1.  
  1. public static void ExportToLocal(string templateFile, string targetFile, params SheetFormatterContainer[] containers)
  1. {
  1. #region 参数验证
  1.  
  1. if (string.IsNullOrWhiteSpace(templateFile))
  1. {
  1. throw new ArgumentNullException("templateFile");
  1. }
  1. if (string.IsNullOrWhiteSpace(targetFile))
  1. {
  1. throw new ArgumentNullException("targetFile");
  1. }
  1. if (!File.Exists(templateFile))
  1. {
  1. throw new FileNotFoundException(templateFile + " 文件不存在!");
  1. }
  1.  
  1. #endregion 参数验证
  1.  
  1. using (FileStream fs = File.OpenWrite(targetFile))
  1. {
  1. var buffer = ExportHelper.ExportToBuffer(templateFile, containers);
  1. fs.Write(buffer, 0, buffer.Length);
  1. fs.Flush();
  1. }
  1. }
  1.  
  1. #endregion 导出到本地
  1.  
  1. #region 导出到Web
  1.  
  1. public static void ExportToWeb(string templateFile, string targetFile, params SheetFormatterContainer[] containers)
  1. {
  1. #region 参数验证
  1.  
  1. if (string.IsNullOrWhiteSpace(templateFile))
  1. {
  1. throw new ArgumentNullException("templateFile");
  1. }
  1. if (string.IsNullOrWhiteSpace(targetFile))
  1. {
  1. throw new ArgumentNullException("targetFile");
  1. }
  1. if (!File.Exists(templateFile))
  1. {
  1. throw new FileNotFoundException(templateFile + " 文件不存在!");
  1. }
  1.  
  1. #endregion 参数验证
  1.  
  1. HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
  1. HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(targetFile, System.Text.Encoding.UTF8));
  1. HttpContext.Current.Response.BinaryWrite(ExportHelper.ExportToBuffer(templateFile, containers));
  1. HttpContext.Current.Response.End();
  1. }
  1.  
  1. #endregion 导出到Web
  1. }
  1. }

Parameter.cs

  1. /*
  1. 类:Parameter
  1. 描述:参数信息
  1. 人:韩兆新 日期:20150117
  1. 修改记录:
  1.  
  1. */
  1.  
  1. using System.Drawing;
  1.  
  1. namespace ExcelReport
  1. {
  1. public class Parameter
  1. {
  1. public Parameter()
  1. {
  1. }
  1.  
  1. public Parameter(string sheetName, string parameterName, Point cellPoint)
  1. {
  1. this.SheetName = sheetName;
  1. this.ParameterName = parameterName;
  1. this.CellPoint = cellPoint;
  1. }
  1.  
  1. public string SheetName { set; get; }
  1.  
  1. public string ParameterName { set; get; }
  1.  
  1. public Point CellPoint { set; get; }
  1. }
  1. }

ParameterCollection.cs

  1. /*
  1. 类:ParameterCollection
  1. 描述:模板中参数信息的集合
  1. 人:韩兆新 日期:20150117
  1. 修改记录:
  1.  
  1. */
  1.  
  1. using System.Collections.Generic;
  1. using System.Drawing;
  1. using System.IO;
  1. using System.Xml.Serialization;
  1.  
  1. namespace ExcelReport
  1. {
  1. public class ParameterCollection
  1. {
  1. protected List<Parameter> parameterList = new List<Parameter>();
  1.  
  1. public Point this[string sheetName, string parameterName]
  1. {
  1. get
  1. {
  1. foreach (Parameter parameter in parameterList)
  1. {
  1. if (parameter.SheetName.Equals(sheetName) && parameter.ParameterName.Equals(parameterName))
  1. {
  1. return parameter.CellPoint;
  1. }
  1. }
  1. return new Point();
  1. }
  1. set
  1. {
  1. bool isExist = false;
  1. foreach (Parameter parameter in parameterList)
  1. {
  1. if (parameter.SheetName.Equals(sheetName) && parameter.ParameterName.Equals(parameterName))
  1. {
  1. isExist = true;
  1. parameter.CellPoint = value;
  1. }
  1. }
  1. if (!isExist)
  1. {
  1. parameterList.Add(new Parameter(sheetName, parameterName, value));
  1. }
  1. }
  1. }
  1.  
  1. public void Load(string xmlPath)
  1. {
  1. string fileName = xmlPath;
  1. if (File.Exists(fileName))
  1. {
  1. XmlSerializer xmlSerializer = new XmlSerializer(parameterList.GetType());
  1. using (Stream reader = new FileStream(fileName, FileMode.Open, FileAccess.Read))
  1. {
  1. parameterList = xmlSerializer.Deserialize(reader) as List<Parameter>;
  1. }
  1. }
  1. else
  1. {
  1. parameterList = new List<Parameter>();
  1. }
  1. }
  1.  
  1. public void Save(string xmlPath)
  1. {
  1. string fileName = xmlPath;
  1. FileInfo fileInfo = new FileInfo(fileName);
  1. DirectoryInfo directoryInfo = fileInfo.Directory;
  1. if (!directoryInfo.Exists)
  1. {
  1. directoryInfo.Create();
  1. }
  1. XmlSerializer xmlSerializer = new XmlSerializer(parameterList.GetType());
  1. using (Stream writer = new FileStream(fileName, FileMode.Create, FileAccess.Write))
  1. {
  1. xmlSerializer.Serialize(writer, parameterList);
  1. }
  1. }
  1. }
  1. }

源码下载:

ExcelReport源码解析的更多相关文章

  1. ExcelReport第二篇:ExcelReport源码解析

    导航 目   录:基于NPOI的报表引擎——ExcelReport 上一篇:使用ExcelReport导出Excel 下一篇:扩展元素格式化器 概述 针对上一篇随笔收到的反馈,在展开对ExcelRep ...

  2. 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

    本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...

  3. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  4. 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

    上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...

  5. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  6. jQuery2.x源码解析(缓存篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 缓存是jQuery中的又一核心设计,jQuery ...

  7. Spring IoC源码解析——Bean的创建和初始化

    Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...

  8. jQuery2.x源码解析(构建篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 笔者阅读了园友艾伦 Aaron的系列博客< ...

  9. jQuery2.x源码解析(设计篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 这一篇笔者主要以设计的角度探索jQuery的源代 ...

随机推荐

  1. mysql5.6设置主从报错1236,Increase max_allowed_packet on master,原因却是Binlog偏移量不对

    在试Mysql5.6,搭了个主从: CHANGE MASTER TO MASTER_HOST='1.2.3.4', master_user='slave', master_password='xxxq ...

  2. Cocos2d-x 3.2 Lua演示样本CocosDenshionTest(音频测试)

    Cocos2d-x 3.2 Lua演示样本CocosDenshionTest(音频测试)  本篇博客介绍Cocos2d-x 3.2中Lua演示样例的音频測试.Cocos2d-x使用SimpleAudi ...

  3. ASP.NET 5 Beta8 发布

    ASP.NET 5 Beta8 发布 ASP.NET 5 的路线图(详见 ASP.NET 5 Schedule and Roadmap : https://github.com/aspnet/home ...

  4. hibernate 多对多 最佳实践

    首先 看看我们 ER 画画 :盖  一对一 .一对多 .多对多 的关系 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvem91dG9uZ3l1YW4=/fo ...

  5. latex如何输入正确的 双引号

    latex当输入双引号,假设直接用双引号键在键盘上.玩过顺-handed. 引述左输入法是正确的:按两次"Tab在之上,数字1左边的键".至于后面行情,该方法是一样的老,这是两次单 ...

  6. nRF905 - 系列示意图

    一个.截图 备份文件:sch20110521.7z 版权声明:本文博客原创文章,博客,未经同意,不得转载.

  7. Struts2详细说明

    最近学习Struts2,阅读一些好的博客.收集有关. 原博文地址:http://blog.csdn.net/zz_mm/article/details/5460397 1.    深入Struts2的 ...

  8. Linux内核分析(三)----初识linux内存管理子系统

    原文:Linux内核分析(三)----初识linux内存管理子系统 Linux内核分析(三) 昨天我们对内核模块进行了简单的分析,今天为了让我们今后的分析没有太多障碍,我们今天先简单的分析一下linu ...

  9. 使用Django清理数据库中的数据

    数据库,数据清洗 问题叙述性说明:在系统我用在,因为历史和由于各种原因,原因记录的数据内的数据库表,有一个问题,有反复和不完整的数据 解:首先.由于数据量还是挺大的,工的清理肯定不行, 然后,我就想写 ...

  10. python 导入库问题

    最终解决如下面:我不知道有没有多余的空间 from django.conf import settings from sys import path path.extend(['/home/zoues ...