├── imgs
├── 10W.png
├── 1000W.png
├── 100W.png
└── 1048576Max.png
├── src
└── main
│ ├── webapp
│ ├── index.jsp
│ └── WEB-INF
│ │ └── web.xml
│ └── java
│ ├── domain
│ └── Student.java
│ ├── controller
│ └── ExcelExportTest.java
│ └── Utils
│ └── ExcelUtil.java
├── README.md
├── pom.xml
├── .gitignore
└── LICENSE
/imgs/10W.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangzhe-inc/large-amount-data-export/HEAD/imgs/10W.png
--------------------------------------------------------------------------------
/src/main/webapp/index.jsp:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello World!
4 |
5 |
6 |
--------------------------------------------------------------------------------
/imgs/1000W.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangzhe-inc/large-amount-data-export/HEAD/imgs/1000W.png
--------------------------------------------------------------------------------
/imgs/100W.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangzhe-inc/large-amount-data-export/HEAD/imgs/100W.png
--------------------------------------------------------------------------------
/imgs/1048576Max.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangzhe-inc/large-amount-data-export/HEAD/imgs/1048576Max.png
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | Archetype Created Web Application
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 基于Apache POI导出大数据量(百万级)Excel的实现
2 | ### 使用POI导出大数据量Excel Demo
3 |
4 | 项目分别模拟了10W,100W,1048576(xlsx最大支持行数)条数据,进行一次性Excel导出。
5 |
6 |
7 | ### 测试:
8 | 模拟10W条数据,一次性导出用时3秒左右(3736ms);
9 | 模拟100W条数据,一次性导出用时26秒左右(26381ms);
10 | 模拟1048576条(xlsx最大支持行数)数据,一次性导出用时27秒左右(27834ms);
11 | (测试图例在imgs文件夹内)
12 |
13 | ### 数据测试环境
14 | 当然,导出速度也和电脑配置相关,以上数据测试环境如下:
15 | 系统:windows 7
16 | 处理器:Inter(R) Core(TM)i5-4590 CPU @ 3.30GHz 3.30GHz
17 | 内存:16 GB
18 | 工具:IntelliJ IDEA
19 |
--------------------------------------------------------------------------------
/src/main/java/domain/Student.java:
--------------------------------------------------------------------------------
1 | package domain;
2 |
3 | import java.util.Date;
4 |
5 | /**
6 | * Created by Cheung on 2017/12/19.
7 | */
8 | public class Student {
9 |
10 | private String name;
11 | private int age;
12 | private Date birthday;
13 | private float height;
14 | private double weight;
15 | private boolean sex;
16 |
17 | public String getName() {
18 | return name;
19 | }
20 |
21 | public void setName(String name) {
22 | this.name = name;
23 | }
24 |
25 | public int getAge() {
26 | return age;
27 | }
28 |
29 | public void setAge(int age) {
30 | this.age = age;
31 | }
32 |
33 | public Date getBirthday() {
34 | return birthday;
35 | }
36 |
37 | public void setBirthday(Date birthday) {
38 | this.birthday = birthday;
39 | }
40 |
41 | public float getHeight() {
42 | return height;
43 | }
44 |
45 | public void setHeight(float height) {
46 | this.height = height;
47 | }
48 |
49 | public double getWeight() {
50 | return weight;
51 | }
52 |
53 | public void setWeight(double weight) {
54 | this.weight = weight;
55 | }
56 |
57 | public boolean isSex() {
58 | return sex;
59 | }
60 |
61 | public void setSex(boolean sex) {
62 | this.sex = sex;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | com.cheung
5 | largeAmountDataExport
6 | war
7 | 1.0-SNAPSHOT
8 | poi Maven Webapp
9 | http://maven.apache.org
10 |
11 |
12 |
13 |
14 |
15 | org.springframework
16 | spring-core
17 | 5.0.2.RELEASE
18 |
19 |
20 |
21 | org.springframework
22 | spring-context
23 | 5.0.2.RELEASE
24 |
25 |
26 |
27 | org.springframework
28 | spring-webmvc
29 | 5.0.2.RELEASE
30 |
31 |
32 |
33 |
34 | commons-io
35 | commons-io
36 | 2.6
37 |
38 |
39 |
40 |
41 |
42 |
43 | org.apache.poi
44 | poi
45 | 3.10-FINAL
46 |
47 |
48 | org.apache.poi
49 | poi-ooxml
50 | 3.10-FINAL
51 |
52 |
53 |
54 | com.alibaba
55 | fastjson
56 | 1.2.4
57 |
58 |
59 |
60 | junit
61 | junit
62 | 3.8.1
63 | test
64 |
65 |
66 |
67 |
68 | largeAmountDataExport
69 |
70 |
71 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### Java template
2 | # Compiled class file
3 | *.class
4 |
5 | # Log file
6 | *.log
7 |
8 | # BlueJ files
9 | *.ctxt
10 |
11 | # Mobile Tools for Java (J2ME)
12 | .mtj.tmp/
13 |
14 | # Package Files #
15 | *.jar
16 | *.war
17 | *.nar
18 | *.ear
19 | *.zip
20 | *.tar.gz
21 | *.rar
22 |
23 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
24 | hs_err_pid*
25 |
26 | ### JetBrains template
27 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
28 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
29 |
30 | # User-specific stuff
31 | .idea/**/workspace.xml
32 | .idea/**/tasks.xml
33 | .idea/**/usage.statistics.xml
34 | .idea/**/dictionaries
35 | .idea/**/shelf
36 |
37 | # Generated files
38 | .idea/**/contentModel.xml
39 |
40 | # Sensitive or high-churn files
41 | .idea/**/dataSources/
42 | .idea/**/dataSources.ids
43 | .idea/**/dataSources.local.xml
44 | .idea/**/sqlDataSources.xml
45 | .idea/**/dynamic.xml
46 | .idea/**/uiDesigner.xml
47 | .idea/**/dbnavigator.xml
48 |
49 | # Gradle
50 | .idea/**/gradle.xml
51 | .idea/**/libraries
52 |
53 | # Gradle and Maven with auto-import
54 | # When using Gradle or Maven with auto-import, you should exclude module files,
55 | # since they will be recreated, and may cause churn. Uncomment if using
56 | # auto-import.
57 | # .idea/artifacts
58 | # .idea/compiler.xml
59 | # .idea/jarRepositories.xml
60 | # .idea/modules.xml
61 | # .idea/*.iml
62 | # .idea/modules
63 | # *.iml
64 | # *.ipr
65 |
66 | # CMake
67 | cmake-build-*/
68 |
69 | # Mongo Explorer plugin
70 | .idea/**/mongoSettings.xml
71 |
72 | # File-based project format
73 | *.iws
74 |
75 | # IntelliJ
76 | out/
77 |
78 | # mpeltonen/sbt-idea plugin
79 | .idea_modules/
80 |
81 | # JIRA plugin
82 | atlassian-ide-plugin.xml
83 |
84 | # Cursive Clojure plugin
85 | .idea/replstate.xml
86 |
87 | # Crashlytics plugin (for Android Studio and IntelliJ)
88 | com_crashlytics_export_strings.xml
89 | crashlytics.properties
90 | crashlytics-build.properties
91 | fabric.properties
92 |
93 | # Editor-based Rest Client
94 | .idea/httpRequests
95 |
96 | # Android studio 3.1+ serialized cache file
97 | .idea/caches/build_file_checksums.ser
98 |
99 | /.idea/
100 | /target/
101 |
--------------------------------------------------------------------------------
/src/main/java/controller/ExcelExportTest.java:
--------------------------------------------------------------------------------
1 | package controller;
2 |
3 | import Utils.ExcelUtil;
4 | import com.alibaba.fastjson.JSONArray;
5 | import domain.Student;
6 |
7 | import java.io.File;
8 | import java.io.FileOutputStream;
9 | import java.io.IOException;
10 | import java.io.OutputStream;
11 | import java.util.ArrayList;
12 | import java.util.Date;
13 | import java.util.LinkedHashMap;
14 |
15 | /**
16 | * Created by Cheung on 2017/12/19.
17 | *
18 | * @author Cheung
19 | * @version 2.0.0
20 | * @date 2018/4/19
21 | */
22 | public class ExcelExportTest {
23 |
24 | public static void main(String[] args) throws IOException {
25 | /**
26 | * 模拟100W条数据,存入JsonArray,此处使用fastJson(号称第一快json解析)快速解析大数据量数据
27 | * 至于容量问题,Java数组的length必须是非负的int,所以它的理论最大值就是java.lang.Integer.MAX_VALUE = 2^31-1 = 2147483647。
28 | * 由于xlsx最大支持行数为1048576行,此处模拟了1048573调数据,剩下的3条占用留给自定义的excel的头信息和列项.
29 | */
30 | // int count = 100000;
31 | // int count = 1000000;
32 | int count = 1048574;
33 | JSONArray studentArray = new JSONArray();
34 | for (int i = 0; i < count; i++) {
35 | Student s = new Student();
36 | s.setName("POI-" + i);
37 | s.setAge(i);
38 | s.setBirthday(new Date());
39 | s.setHeight(i);
40 | s.setWeight(i);
41 | s.setSex(i % 2 != 0);
42 | studentArray.add(s);
43 | }
44 |
45 | /*
46 | * titleList存放了2个元素,分别为titleMap和headMap
47 | */
48 | ArrayList titleList = new ArrayList();
49 | // 1.titleMap存放了该excel的头信息
50 | LinkedHashMap titleMap = new LinkedHashMap();
51 | titleMap.put("title1", "POI导出大数据量Excel Demo");
52 | titleMap.put("title2", "https://github.com/550690513");
53 | // 2.headMap存放了该excel的列项
54 | LinkedHashMap headMap = new LinkedHashMap();
55 | headMap.put("name", "姓名");
56 | headMap.put("age", "年龄");
57 | headMap.put("birthday", "生日");
58 | headMap.put("height", "身高");
59 | headMap.put("weight", "体重");
60 | headMap.put("sex", "性别");
61 |
62 | titleList.add(titleMap);
63 | titleList.add(headMap);
64 |
65 |
66 | File file = new File("D://ExcelExportDemo/");
67 | if (!file.exists()) file.mkdirs();// 创建该文件夹目录
68 | OutputStream os = null;
69 | try {
70 | System.out.println("正在导出xlsx...");
71 | long start = System.currentTimeMillis();
72 | // .xlsx格式
73 | os = new FileOutputStream(file.getAbsolutePath() + File.separator + start + ".xlsx");
74 | ExcelUtil.exportExcel(titleList, studentArray, os);
75 | System.out.println("导出完成...共" + count + "条数据,用时" + (System.currentTimeMillis() - start) + "毫秒");
76 | System.out.println("文件路径:" + file.getAbsolutePath() + File.separator + start + ".xlsx");
77 | } catch (Exception e) {
78 | e.printStackTrace();
79 | } finally {
80 | if (os != null) {
81 | os.close();
82 | }
83 | }
84 |
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/Utils/ExcelUtil.java:
--------------------------------------------------------------------------------
1 | package Utils;
2 |
3 | import com.alibaba.fastjson.JSONArray;
4 | import com.alibaba.fastjson.JSONObject;
5 | import domain.Student;
6 | import org.apache.poi.common.usermodel.Hyperlink;
7 | import org.apache.poi.hpsf.SummaryInformation;
8 | import org.apache.poi.hssf.usermodel.*;
9 | import org.apache.poi.hssf.util.HSSFColor;
10 | import org.apache.poi.ss.usermodel.CellStyle;
11 | import org.apache.poi.ss.usermodel.CreationHelper;
12 | import org.apache.poi.ss.usermodel.Font;
13 | import org.apache.poi.ss.usermodel.Row;
14 | import org.apache.poi.ss.util.CellRangeAddress;
15 | import org.apache.poi.xssf.streaming.SXSSFCell;
16 | import org.apache.poi.xssf.streaming.SXSSFRow;
17 | import org.apache.poi.xssf.streaming.SXSSFSheet;
18 | import org.apache.poi.xssf.streaming.SXSSFWorkbook;
19 | import org.apache.poi.xssf.usermodel.*;
20 |
21 | import java.io.*;
22 | import java.math.BigDecimal;
23 | import java.text.SimpleDateFormat;
24 | import java.util.*;
25 |
26 | /**
27 | * Created by Cheung on 2017/12/19.
28 | *
29 | * Apache POI操作Excel对象
30 | * HSSF:操作Excel 2007之前版本(.xls)格式,生成的EXCEL不经过压缩直接导出
31 | * XSSF:操作Excel 2007及之后版本(.xlsx)格式,内存占用高于HSSF
32 | * SXSSF:从POI3.8 beta3开始支持,基于XSSF,低内存占用,专门处理大数据量(建议)。
33 | *
34 | * 注意:
35 | * 值得注意的是SXSSFWorkbook只能写(导出)不能读(导入)
36 | *
37 | * 说明:
38 | * .xls格式的excel(最大行数65536行,最大列数256列)
39 | * .xlsx格式的excel(最大行数1048576行,最大列数16384列)
40 | */
41 | public class ExcelUtil {
42 |
43 | public static final String DEFAULT_DATE_PATTERN = "yyyy年MM月dd日";// 默认日期格式
44 | public static final int DEFAULT_COLUMN_WIDTH = 17;// 默认列宽
45 |
46 |
47 | /**
48 | * 导出Excel(.xlsx)格式
49 | * @param titleList 表格头信息集合
50 | * @param dataArray 数据数组
51 | * @param os 文件输出流
52 | */
53 | public static void exportExcel(ArrayList titleList, JSONArray dataArray, OutputStream os) {
54 | String datePattern = DEFAULT_DATE_PATTERN;
55 | int minBytes = DEFAULT_COLUMN_WIDTH;
56 |
57 | /**
58 | * 声明一个工作薄
59 | */
60 | SXSSFWorkbook workbook = new SXSSFWorkbook(1000);// 大于1000行时会把之前的行写入硬盘
61 | workbook.setCompressTempFiles(true);
62 |
63 | // 表头1样式
64 | CellStyle title1Style = workbook.createCellStyle();
65 | title1Style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 水平居中
66 | title1Style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
67 | Font titleFont = workbook.createFont();// 字体
68 | titleFont.setFontHeightInPoints((short) 20);
69 | titleFont.setBoldweight((short) 700);
70 | title1Style.setFont(titleFont);
71 |
72 | // 表头2样式
73 | CellStyle title2Style = workbook.createCellStyle();
74 | title2Style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
75 | title2Style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
76 | title2Style.setBorderTop(HSSFCellStyle.BORDER_THIN);// 上边框
77 | title2Style.setBorderRight(HSSFCellStyle.BORDER_THIN);// 右
78 | title2Style.setBorderBottom(HSSFCellStyle.BORDER_THIN);// 下
79 | title2Style.setBorderLeft(HSSFCellStyle.BORDER_THIN);// 左
80 | Font title2Font = workbook.createFont();
81 | title2Font.setUnderline((byte) 1);
82 | title2Font.setColor(HSSFColor.BLUE.index);
83 | title2Style.setFont(title2Font);
84 |
85 | // head样式
86 | CellStyle headerStyle = workbook.createCellStyle();
87 | headerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
88 | headerStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
89 | headerStyle.setFillForegroundColor(HSSFColor.LIGHT_GREEN.index);// 设置颜色
90 | headerStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);// 前景色纯色填充
91 | headerStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
92 | headerStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
93 | headerStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
94 | headerStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
95 | Font headerFont = workbook.createFont();
96 | headerFont.setFontHeightInPoints((short) 12);
97 | headerFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
98 | headerStyle.setFont(headerFont);
99 |
100 | // 单元格样式
101 | CellStyle cellStyle = workbook.createCellStyle();
102 | cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
103 | cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
104 | cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
105 | cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
106 | cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
107 | cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
108 | Font cellFont = workbook.createFont();
109 | cellFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
110 | cellStyle.setFont(cellFont);
111 |
112 |
113 | String title1 = (String) titleList.get(0).get("title1");
114 | String title2 = (String) titleList.get(0).get("title2");
115 | LinkedHashMap headMap = titleList.get(1);
116 |
117 | /**
118 | * 生成一个(带名称)表格
119 | */
120 | SXSSFSheet sheet = (SXSSFSheet) workbook.createSheet(title1);
121 | sheet.createFreezePane(0, 3, 0, 3);// (单独)冻结前三行
122 |
123 | /**
124 | * 生成head相关信息+设置每列宽度
125 | */
126 | int[] colWidthArr = new int[headMap.size()];// 列宽数组
127 | String[] headKeyArr = new String[headMap.size()];// headKey数组
128 | String[] headValArr = new String[headMap.size()];// headVal数组
129 | int i = 0;
130 | for (Map.Entry entry : headMap.entrySet()) {
131 | headKeyArr[i] = entry.getKey();
132 | headValArr[i] = entry.getValue();
133 |
134 | int bytes = headKeyArr[i].getBytes().length;
135 | colWidthArr[i] = bytes < minBytes ? minBytes : bytes;
136 | sheet.setColumnWidth(i, colWidthArr[i] * 256);// 设置列宽
137 | i++;
138 | }
139 |
140 |
141 | /**
142 | * 遍历数据集合,产生Excel行数据
143 | */
144 | int rowIndex = 0;
145 | for (Object obj : dataArray) {
146 | // 生成title+head信息
147 | if (rowIndex == 0) {
148 | SXSSFRow title1Row = (SXSSFRow) sheet.createRow(0);// title1行
149 | title1Row.createCell(0).setCellValue(title1);
150 | title1Row.getCell(0).setCellStyle(title1Style);
151 | sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headMap.size() - 1));// 合并单元格
152 |
153 | SXSSFRow title2Row = (SXSSFRow) sheet.createRow(1);// title2行
154 | title2Row.createCell(0).setCellValue(title2);
155 |
156 | CreationHelper createHelper = workbook.getCreationHelper();
157 | XSSFHyperlink hyperLink = (XSSFHyperlink) createHelper.createHyperlink(Hyperlink.LINK_URL);
158 | hyperLink.setAddress(title2);
159 | title2Row.getCell(0).setHyperlink(hyperLink);// 添加超链接
160 |
161 | title2Row.getCell(0).setCellStyle(title2Style);
162 | sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, headMap.size() - 1));// 合并单元格
163 |
164 | SXSSFRow headerRow = (SXSSFRow) sheet.createRow(2);// head行
165 | for (int j = 0; j < headValArr.length; j++) {
166 | headerRow.createCell(j).setCellValue(headValArr[j]);
167 | headerRow.getCell(j).setCellStyle(headerStyle);
168 | }
169 | rowIndex = 3;
170 | }
171 |
172 | JSONObject jo = (JSONObject) JSONObject.toJSON(obj);
173 | // 生成数据
174 | SXSSFRow dataRow = (SXSSFRow) sheet.createRow(rowIndex);// 创建行
175 | for (int k = 0; k < headKeyArr.length; k++) {
176 | SXSSFCell cell = (SXSSFCell) dataRow.createCell(k);// 创建单元格
177 | Object o = jo.get(headKeyArr[k]);
178 | String cellValue = "";
179 |
180 | if (o == null) {
181 | cellValue = "";
182 | } else if (o instanceof Date) {
183 | cellValue = new SimpleDateFormat(datePattern).format(o);
184 | } else if (o instanceof Float || o instanceof Double) {
185 | cellValue = new BigDecimal(o.toString()).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
186 | } else {
187 | cellValue = o.toString();
188 | }
189 |
190 | if (cellValue.equals("true")) {
191 | cellValue = "男";
192 | } else if (cellValue.equals("false")) {
193 | cellValue = "女";
194 | }
195 |
196 | cell.setCellValue(cellValue);
197 | cell.setCellStyle(cellStyle);
198 | }
199 | rowIndex++;
200 | }
201 |
202 | try {
203 | workbook.write(os);
204 | os.flush();// 刷新此输出流并强制将所有缓冲的输出字节写出
205 | os.close();// 关闭流
206 | workbook.dispose();// 释放workbook所占用的所有windows资源
207 | } catch (IOException e) {
208 | e.printStackTrace();
209 | }
210 | }
211 |
212 | }
213 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------