> dataList = model.dataList;
82 | inp = new FileInputStream(filepath);
83 | int rownum = dataList.size();
84 | int columnum = dataList.get(0).size();
85 |
86 | HSSFWorkbook wb = new HSSFWorkbook();
87 | HSSFSheet sheet = wb.createSheet("sheet1");
88 | for (int i = 0; i < rownum; i++) {
89 | // System.out.println("i:"+i);
90 | Row row = sheet.createRow(i);
91 | for (int j = 0; j < columnum; j++) {
92 | /* System.out.println("j:"+j); */
93 | Cell cell = row.createCell(j);
94 | // 设置格式
95 | cell.setCellType(CellType.NUMERIC);
96 | // 设置值
97 | cell.setCellValue(dataList.get(i).get(j));
98 | }
99 | }
100 | // Write the output to a file
101 | FileOutputStream fileOut = new FileOutputStream(filepath);
102 | wb.write(fileOut);
103 | fileOut.close();
104 | inp.close();
105 | } catch (Exception e) {
106 | e.printStackTrace();
107 | StringBuilder builder = new StringBuilder();
108 | StackTraceElement[] stackTrace = e.getStackTrace();
109 | for (StackTraceElement element : stackTrace) {
110 | builder.append(element.toString() + "\n");
111 | }
112 | return builder.toString();
113 | }
114 | return "success";
115 | }
116 |
117 | // XSSF对应的是xlsx格式
118 | private static void poiwriteXlsx(ExcelView.TableValueModel model, String filepath) {
119 | InputStream inp;
120 | ifexist(filepath);
121 | try {
122 | inp = new FileInputStream(filepath);
123 | int rownum = model.dataList.size();
124 | int columnum = model.dataList.get(0).size();
125 | Workbook wb = WorkbookFactory.create(inp);
126 | Sheet sheet = wb.createSheet("sheet1");
127 | for (int i = 0; i < rownum; i++) {
128 | // System.out.println("i:"+i);
129 | Row row = sheet.createRow(i);
130 | for (int j = 0; j < columnum; j++) {
131 | /* System.out.println("j:"+j); */
132 | Cell cell = row.createCell(j);
133 | // 设置格式
134 | cell.setCellType(CellType.STRING);
135 | // 设置值
136 | cell.setCellValue(model.dataList.get(i).get(j));
137 | }
138 | }
139 | // Write the output to a file
140 | FileOutputStream fileOut = new FileOutputStream(filepath);
141 | wb.write(fileOut);
142 | fileOut.close();
143 | inp.close();
144 | System.out.println("写入完成");
145 | } catch (Exception e) {
146 | // TODO Auto-generated catch block
147 | e.printStackTrace();
148 | }
149 | }
150 |
151 | // 传入文件的地址,判断文件是否存在,如果不存在的话创建该文件
152 | // 这个功能好像还存在一个小BUG,直接createNewFile();的文件不能用,以后找方法解决。
153 | public static void ifexist(String path) {
154 | try {
155 | File file = new File(path);
156 | if (!file.exists()) {
157 | System.out.println("文件不存在,创建该文件,文件地址为:" + path);
158 | file.createNewFile();
159 | }
160 | } catch (Exception e) {
161 | // TODO Auto-generated catch block
162 | e.printStackTrace();
163 | }
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/common_button_b3b8c1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/common_dialog_keyboard_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/PoiLib/src/main/res/drawable/common_dialog_keyboard_close.png
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/common_divider_ffffff.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/common_execl_range_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/PoiLib/src/main/res/drawable/common_execl_range_icon.png
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/common_keyboard_btn_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | -
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/common_keyboard_del2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/PoiLib/src/main/res/drawable/common_keyboard_del2.png
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/common_keyboard_item_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/common_progress_drag_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/PoiLib/src/main/res/drawable/common_progress_drag_button.png
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/common_rect_0062ff_hollow.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/common_rect_c9ced4_hollow.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/common_rect_r2_2870f6_shadow.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/common_seekbar_style2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
11 | -
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/drawable/original_common_corner_ffffff_r7.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 16dp
3 |
--------------------------------------------------------------------------------
/PoiLib/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ExcelView-POI
3 |
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ExcelView
2 |
3 | ## 项目介绍
4 | 项目是仿照WPS中Excel的功能实现的,实现了显示,滑动,编辑等基本功能,并且结构简单,可扩展性强,绘制性能较高。
5 | 项目分为两个支持库:
6 | ### ExcelViewLib:
7 | 实现高性能表格控件的绘制,并支持各种交互方式的输入,可扩展性高。
8 | 使用方式:implementation 'io.github.september26:excelview:0.9.4'
9 |
10 | ### PoiLib:
11 | 打包POI的所有需要的所有jar包,并针对安卓进行针对性适配改动,实现了安卓设备上读写excel的功能。如果只有安卓上使用POI需求的同学,只依赖这个库即可。
12 | 使用方式:implementation 'io.github.september26:excelview-poi:0.9.4'
13 |
14 | 项目还有一些excel的功能未实现,比如公式计算,自动扩展等等,希望后续使用的人能够一起参与进来,逐渐的进行完善和扩展。
15 | 同步CSDN介绍:https://blog.csdn.net/rzleilei/article/details/121016009
16 |
17 | ## 效果简介
18 | **整体效果图**
19 | 
20 |
21 | **拖动效果图**
22 | 
23 |
24 | **范围选择效果图**
25 | 
26 |
27 | **非编辑区域选择效果图**
28 | 
29 |
30 | **编辑效果图**
31 | 
32 |
33 | ## 核心元素介绍
34 | 采用组合的设计模式,主要对象有以下几个,
35 | * ExcelView:负责数据以及各种状态的渲染。
36 | * ExcelEditDialog:选中某个cell后弹出复制,粘贴,加减乘除等选择框。
37 | * KeyBoardDialog:负责对选中数据的编辑操作。
38 | * ExcelControl:逻辑处理器。负责以上三个对象之间的关系关联。后续的导出xls功能,也通过由其负责串联。
39 | * CommonSeekBar,CommonVerticalSeekBar:横向纵向的滚动条。
40 |
41 |
42 | ## 使用介绍
43 | * 1.参照sample中的使用方法,build.gradle中添加依赖库:'io.github.september26:excelview:0.9.4'
44 | * 2.参照app中Fragment1和Fragment2中的使用方法,直接使用ExcelControlImpl中已经写好的组合逻辑,或者继承ExcelControlImpl重写其组合逻辑。
45 | * 3.可扩展性:可通过继承ControlImpl重写其方法实现不同的业务场景逻辑。
46 | * 4.可扩展性:可自定义Dialog,通过ControlImpl和ExcelView组合实现对应场景逻辑。
47 | * 5.如果需要安卓上读写excel的能力,请添加依赖库'io.github.september26:excelview-poi:0.9.4'。使用PoiUtil进行读写操作。
48 |
49 | ## 后续计划
50 | * 1.添加excel导出为xls文件功能。(PS :0.9.4的版本已完成。2022.2.9)
51 | * 2.拆分页面绘制和excel文件读写为两个支持库。(PS :0.9.4的版本已完成。2022.2.9)
52 | * 3.看issues中的需求。
53 |
54 |
55 | ## 实现逻辑介绍
56 | WPS中excel实现了相当多的功能,不可能完全都实现,所以本项目聚焦于其核心功能实现即可。
57 | 核心功能总结下来就是读,写,存这三点,围绕这三点,我们整理下我们要实现的需求点:
58 | * 1.在一屏幕的范围内显示几十甚至上百个Cell,并且不能卡顿。
59 | * 2.一屏显示不下时,可以横向,纵向,斜向拖动表格,并且滑动流畅。
60 | * 3.横向,纵向标题的实现。
61 | * 4.可以进行单元格的选中。
62 | * 5.可以通过拖动的方式实现批量的选择。
63 | * 6.不可编辑区域的实现。
64 | * 7.可以针对选中的单元格进行数据上的修改操作。
65 | * 8.显示弹出框,支持对数据进行修。
66 | * 9.修改的数据进行变色显示。
67 | * 10.横向,纵向标题的实现。
68 | * 11.编辑好的数据,可以导出到xls和xlsx文件当中.
69 |
70 | 围绕这11个需求点,我们挨个去讨论下如何去实现。
71 | * **1.在一屏幕的范围内显示几十甚至上百个Cell,并且不能卡顿。**
72 | 大批量的显示数据,第一个想到的肯定是RecyclerView搭配GridLayout,但是实际上简单试了下,由于RecyclerView的原理仍然是每个Cell都需要单独创建,所以效率是很低的,采用RecyclerView的
73 | 方案会导致首次进入相当的卡顿,所以这个方案弃用。想要高效率的绘制,我们首先要了解下整个View的渲染流程,这里就不详细展开了,我们实现的核心就是用一个View去实现所有的功能,抛出掉measure和layout 方法,只重写draw方法。因为View的数量多少对draw方法影响是很小的。所以最终决定采用Canvas自绘的方式,所以的内容,分割线的位置都一次性计算好,然后通过canvas进行绘制。
74 |
75 | * **2.一屏显示不下时,可以横向,纵向,斜向拖动表格,并且滑动流畅。**
76 | 假设我们横向有10个cell,但是横向一屏只能显示5个cell,那我们想显示4到9的cell时怎么办呢?这里我想了一个简单的实现方案,还是按照10个去计算,显示4到9的时候,只要每个cell的x值都减去4个cell的 宽度即可。这样第0到4个cell,会因为x轴计算为负数而被挤出屏幕,也就不会在屏幕内显示了。高度的实现原理也是一样的。
77 |
滑动自然采用的是重写dispatchTouchEvent方法计算横向纵向偏移的方式。
78 |
79 | * **3.横向,纵向标题的实现。**
80 | 横向标题和纵向标题,这个需要逻辑特殊处理下。横向标题的话,一样计算一个偏移量,然后每个cell的Y坐标都在基础之上增加这个偏移量。纵向原理类似。
81 |
82 |
83 | * **4.可以进行单元格的选中。**
84 | 单元格选中是下面这种样式的,实现不难,因为单元格是挨个计算的,所以计算到这个单元格的时候,额外添加样式即可。
85 | 但是因为绘制选中单元格肯定会影响四周的单元格,所以我这里进行了两遍绘制,先绘制所有单元格,然后再去绘制选中单元格,选中单元格的样式是直接覆盖上去的。
86 |
87 | * **5.可以通过拖动的方式实现批量的选择。**
88 | 拖动选择和拖动表格都用到了手势监听,所以肯定会有冲突。我这里的解决方案就是看是否先选中,如果选中了某个cell则认为是拖动选择,否则认为是拖动表格。
89 |
90 | * **6.不可编辑区域的实现。**
91 | 手势滑动,滑动结束后计算坐标,如果在不可编辑区域,则把选中的范围做适当的修改。
92 |
93 | * **7.可以针对选中的单元格进行数据上的修改操作。**
94 | 个人很欣赏RcyclerView的组合模式,所以这里我也使用了组合的设计模式。ExcelView本身只注重数据的渲染和选择,修改,变色等等所有的逻辑都交给外部类来控制。
95 |
96 | * **8.显示弹出框,支持对数据进行修改。**
97 | 组合模式分为三块,弹出框Dialog, ExcelView,组合器Control。编辑的弹出框并不直接和ExcelView绑定,而是通过Control来实现一个双向的绑定。
98 | 这样ExcelView可以适配不同的Dialog,同样的Dialog也可以适配不同的ExcelView。
99 |
100 | * **9.修改的数据进行变色显示。**
101 | ExcelView提供一个功能,设置范围的颜色,由外部来调用。这样不仅仅修改后可以进行变色,用户完全可以根据特定场景,根据自己的选择来使用。
102 |
103 | * **0.横向纵向拖动条的显示。**
104 | 这个实现难点在于纵向的滑动条。借鉴网上的方案进行了实现。也放到项目里面供选择使用。
105 |
106 | * **11.编辑好的数据,可以导出到xls和xlsx文件当中。**
107 | xls格式已经实现,xlsx格式也已经实现
108 |
109 | ## 更新记录;
110 | 2021.11.30:支持xlsx格式的读取和写入
111 | 2021.11.01:发布到mavenCenter仓库
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | }
4 |
5 | android {
6 | compileSdk 31
7 |
8 | defaultConfig {
9 | applicationId "com.xt.excelview.demo"
10 | minSdk 26
11 | targetSdk 31
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | compileOptions {
25 | sourceCompatibility JavaVersion.VERSION_1_8
26 | targetCompatibility JavaVersion.VERSION_1_8
27 | }
28 | buildFeatures {
29 | viewBinding true
30 | }
31 | }
32 |
33 | dependencies {
34 |
35 | implementation 'androidx.appcompat:appcompat:1.2.0'
36 | implementation 'com.google.android.material:material:1.3.0'
37 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
38 | implementation 'androidx.navigation:navigation-fragment:2.3.5'
39 | implementation 'androidx.navigation:navigation-ui:2.3.5'
40 | // testImplementation 'junit:junit:4.+'
41 | // androidTestImplementation 'androidx.test.ext:junit:1.1.2'
42 | // androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
43 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.0"
44 | implementation project(':ExcelViewLib')
45 | implementation project(':PoiLib')
46 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/assets/demo.xls:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/app/src/main/assets/demo.xls
--------------------------------------------------------------------------------
/app/src/main/assets/demo.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/app/src/main/assets/demo.xlsx
--------------------------------------------------------------------------------
/app/src/main/java/com/xt/excelview/Fragment1.java:
--------------------------------------------------------------------------------
1 | package com.xt.excelview;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import androidx.annotation.NonNull;
9 | import androidx.annotation.Nullable;
10 | import androidx.fragment.app.Fragment;
11 |
12 | import com.xt.excelview.databinding.FragmentFirstBinding;
13 | import com.xt.excelview.lib.control.ExcelControlInter;
14 | import com.xt.excelview.lib.control.ExcelControlImpl;
15 | import com.xt.excelview.lib.view.ExcelView;
16 |
17 | import java.math.BigDecimal;
18 | import java.util.ArrayList;
19 |
20 | /**
21 | * demo1样例
22 | * 直接使用ExcelControlImpl以及其中的逻辑
23 | *
24 | * @author lxl
25 | */
26 | public class Fragment1 extends Fragment {
27 |
28 | private FragmentFirstBinding binding;
29 |
30 | @Override
31 | public View onCreateView(
32 | LayoutInflater inflater, ViewGroup container,
33 | Bundle savedInstanceState
34 | ) {
35 |
36 | binding = FragmentFirstBinding.inflate(inflater, container, false);
37 | return binding.getRoot();
38 | }
39 |
40 | @Override
41 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
42 | super.onViewCreated(view, savedInstanceState);
43 | ExcelControlInter control = new ExcelControlImpl(binding.excelView, binding.scrollX, binding.scrollY, null);
44 | ExcelView.TableValueModel tableValueModel = getModel();
45 | //进行绑定
46 | control.bindData(tableValueModel);
47 | }
48 |
49 | @Override
50 | public void onDestroyView() {
51 | super.onDestroyView();
52 | binding = null;
53 | }
54 |
55 | public ExcelView.TableValueModel getModel() {
56 | ExcelView.TableValueModel model = new ExcelView.TableValueModel();
57 | model.columnTitle = "纵向标题";
58 | model.rowTitle = "横向标题";
59 | model.onlyReadXNum = 2;
60 | model.onlyReadYNum = 1;
61 |
62 | //横向,纵向都设置为30格
63 | int size = 30;
64 | for (int i = 1; i < size; i++) {
65 | ArrayList strings = new ArrayList<>();
66 | for (int j = 1; j < size; j++) {
67 | strings.add(new BigDecimal(i + (double) j / 100.0).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
68 | }
69 | model.dataList.add(strings);
70 | }
71 | model.rows = model.dataList.size();
72 | model.columns = model.dataList.get(0).size();
73 | return model;
74 | }
75 |
76 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/xt/excelview/Fragment2.java:
--------------------------------------------------------------------------------
1 | package com.xt.excelview;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import androidx.annotation.NonNull;
9 | import androidx.fragment.app.Fragment;
10 |
11 | import com.xt.excelview.custom.CustomControlImpl;
12 | import com.xt.excelview.databinding.FragmentSecondBinding;
13 | import com.xt.excelview.lib.control.ExcelControlInter;
14 | import com.xt.excelview.lib.view.ExcelView;
15 |
16 | import java.math.BigDecimal;
17 | import java.util.ArrayList;
18 |
19 | public class Fragment2 extends Fragment {
20 |
21 | private FragmentSecondBinding binding;
22 |
23 | @Override
24 | public View onCreateView(
25 | LayoutInflater inflater, ViewGroup container,
26 | Bundle savedInstanceState
27 | ) {
28 | binding = FragmentSecondBinding.inflate(inflater, container, false);
29 | return binding.getRoot();
30 | }
31 |
32 | public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
33 | super.onViewCreated(view, savedInstanceState);
34 | ExcelControlInter control = new CustomControlImpl(binding.excelView, null);
35 | ExcelView.TableValueModel tableValueModel = getModel();
36 | //进行绑定
37 | control.bindData(tableValueModel);
38 | }
39 |
40 | @Override
41 | public void onDestroyView() {
42 | super.onDestroyView();
43 | binding = null;
44 | }
45 |
46 | public ExcelView.TableValueModel getModel() {
47 | ExcelView.TableValueModel model = new ExcelView.TableValueModel();
48 | model.columnTitle = "纵向标题";
49 | model.rowTitle = "横向标题";
50 | model.onlyReadXNum = 2;
51 | model.onlyReadYNum = 1;
52 |
53 | //横向,纵向都设置为30格
54 | int size = 30;
55 | for (int i = 1; i < size; i++) {
56 | ArrayList strings = new ArrayList<>();
57 | for (int j = 1; j < size; j++) {
58 | strings.add(new BigDecimal(i + (double) j / 100.0).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
59 | }
60 | model.dataList.add(strings);
61 | }
62 | model.rows = model.dataList.size();
63 | model.columns = model.dataList.get(0).size();
64 | return model;
65 | }
66 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/xt/excelview/Fragment3.java:
--------------------------------------------------------------------------------
1 | package com.xt.excelview;
2 |
3 | import android.os.Bundle;
4 | import android.util.Log;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.annotation.Nullable;
11 | import androidx.fragment.app.Fragment;
12 |
13 | import com.xt.excelview.custom.CustomControlImpl;
14 | import com.xt.excelview.databinding.FragmentThirdBinding;
15 | import com.xt.excelview.util.IOHelper;
16 | import com.xt.excelview.lib.control.ExcelControlInter;
17 | import com.xt.excelview.lib.view.ExcelView;
18 | import com.xt.excelview.poi.poi.PoiUtil;
19 |
20 | import java.io.File;
21 | import java.io.IOException;
22 | import java.io.InputStream;
23 |
24 | public class Fragment3 extends Fragment {
25 |
26 | private FragmentThirdBinding binding;
27 | private final String FILE_NAME = "demo";
28 | private String FILE_PATH;
29 |
30 | @Override
31 | public void onCreate(@Nullable Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | FILE_PATH = getActivity().getFilesDir().getAbsolutePath() + File.separator;
34 | }
35 |
36 | @Override
37 | public View onCreateView(
38 | LayoutInflater inflater, ViewGroup container,
39 | Bundle savedInstanceState
40 | ) {
41 | binding = FragmentThirdBinding.inflate(inflater, container, false);
42 | return binding.getRoot();
43 | }
44 |
45 | public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
46 | super.onViewCreated(view, savedInstanceState);
47 | //拷贝文件到data/file目录下,然后跳转
48 | Bundle arguments = getArguments();
49 | String type = "xls";
50 | if (arguments != null) {
51 | type = arguments.getString("type");
52 | }
53 | String fileName = FILE_NAME + "." + type;
54 | String filePath = FILE_PATH + fileName;
55 | File file = new File(filePath);
56 | if (!file.exists()) {
57 | try {
58 | InputStream open = getActivity().getAssets().open(fileName);
59 | IOHelper.copyFileFromInputStream(open, file);
60 | } catch (IOException e) {
61 | e.printStackTrace();
62 | }
63 | }
64 | showExcel(file, filePath);
65 | }
66 |
67 | private void showExcel(File file, String filePath) {
68 | ExcelControlInter control = new CustomControlImpl(binding.excelView, null);
69 | ExcelView.TableValueModel model = PoiUtil.readExcel(file);
70 | Log.i("lxltest", "model:" + model.dataList.size());
71 | //进行绑定
72 | control.bindData(model);
73 |
74 | binding.buttonSave.setOnClickListener(v -> {
75 | //很对model生成
76 | PoiUtil.write2Excel(filePath, model);
77 | });
78 | }
79 |
80 | @Override
81 | public void onDestroyView() {
82 | super.onDestroyView();
83 | binding = null;
84 | }
85 |
86 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/xt/excelview/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.xt.excelview;
2 |
3 | import android.os.Bundle;
4 |
5 | import androidx.appcompat.app.AppCompatActivity;
6 | import androidx.fragment.app.Fragment;
7 | import androidx.fragment.app.FragmentTransaction;
8 |
9 | import com.xt.excelview.databinding.ActivityMainBinding;
10 |
11 |
12 | public class MainActivity extends AppCompatActivity {
13 |
14 | private ActivityMainBinding binding;
15 | private Fragment1 firstFragment;
16 | private Fragment2 secondFragment;
17 | private Fragment3 thirdFragment;
18 | private int REQUEST_CODE = 1;
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | binding = ActivityMainBinding.inflate(getLayoutInflater());
24 | setContentView(binding.getRoot());
25 |
26 |
27 | binding.buttonFirst.setOnClickListener(v -> {
28 | if (firstFragment == null) {
29 | firstFragment = new Fragment1();
30 | }
31 | showFragment(firstFragment);
32 | });
33 |
34 | binding.buttonSecond.setOnClickListener(v -> {
35 | if (secondFragment == null) {
36 | secondFragment = new Fragment2();
37 | }
38 | showFragment(secondFragment);
39 | });
40 |
41 | binding.buttonThird.setOnClickListener(v -> {
42 | if (thirdFragment == null) {
43 | thirdFragment = new Fragment3();
44 | }
45 | Bundle bundle = new Bundle();
46 | bundle.putString("type", "xls");
47 | thirdFragment.setArguments(bundle);
48 | showFragment(thirdFragment);
49 | });
50 |
51 | binding.buttonFourth.setOnClickListener(v -> {
52 | if (thirdFragment == null) {
53 | thirdFragment = new Fragment3();
54 | }
55 | Bundle bundle = new Bundle();
56 | bundle.putString("type", "xlsx");
57 | thirdFragment.setArguments(bundle);
58 | showFragment(thirdFragment);
59 | });
60 | }
61 |
62 | private void showFragment(Fragment fragment) {
63 | FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
64 | if (!fragment.isAdded()) {
65 | fragmentTransaction.add(android.R.id.content, fragment);
66 | fragmentTransaction.addToBackStack(null);
67 | fragmentTransaction.commit();
68 | } else {
69 | fragmentTransaction.show(fragment);
70 | }
71 | }
72 |
73 | // private void requestPermission(Context context) {
74 | // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
75 | // // 先判断有没有权限
76 | // if (Environment.isExternalStorageManager()) {
77 | // readFile();
78 | // } else {
79 | // Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
80 | // intent.setData(Uri.parse("package:" + context.getPackageName()));
81 | // startActivityForResult(intent, REQUEST_CODE);
82 | // }
83 | // } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
84 | // // 先判断有没有权限
85 | // if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
86 | // ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
87 | // readFile();
88 | // } else {
89 | // ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
90 | // }
91 | // } else {
92 | // readFile();
93 | // }
94 | // }
95 | //
96 | // public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
97 | // super.onRequestPermissionsResult(requestCode, permissions, grantResults);
98 | // if (requestCode == REQUEST_CODE) {
99 | // if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
100 | // ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
101 | // readFile();
102 | // } else {
103 | // Toast.makeText(this, "存储权限获取失败", Toast.LENGTH_LONG).show();
104 | // }
105 | // }
106 | // }
107 | //
108 | // protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
109 | // super.onActivityResult(requestCode, resultCode, data);
110 | // if (requestCode == REQUEST_CODE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
111 | // if (Environment.isExternalStorageManager()) {
112 | // readFile();
113 | // } else {
114 | // Toast.makeText(this, "存储权限获取失败", Toast.LENGTH_LONG).show();
115 | // }
116 | // }
117 | // }
118 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/xt/excelview/custom/CustomControlImpl.java:
--------------------------------------------------------------------------------
1 | package com.xt.excelview.custom;
2 |
3 | import android.graphics.Color;
4 | import android.view.Gravity;
5 | import android.view.View;
6 | import android.widget.Toast;
7 |
8 | import com.xt.excelview.lib.control.ExcelControlImpl;
9 | import com.xt.excelview.lib.dialog.KeyBoardCenterDialog;
10 | import com.xt.excelview.lib.dialog.KeyBoardDialog;
11 | import com.xt.excelview.lib.util.DeviceUtil;
12 | import com.xt.excelview.lib.view.ExcelView;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * 开发者自定义
18 | */
19 | public class CustomControlImpl extends ExcelControlImpl {
20 |
21 | public CustomControlImpl(ExcelView excelView, View.OnClickListener listener) {
22 | super(excelView, listener);
23 | }
24 |
25 | @Override
26 | public void showKeyboard(ExcelView.TableValueModel tableModel, int[] selectRange, int selectType) {
27 | //这里使用KeyBoardCenterDialog替换原来的KeyBoardDialog,从而实现不一样的显示效果
28 | List> dataList = tableModel.dataList;
29 | KeyBoardCenterDialog popWin = new KeyBoardCenterDialog(context, DeviceUtil.getScreenSize(context)[0], dipUnit * 137);
30 | KeyBoardDialog.DialogModel dialogModel = new KeyBoardDialog.DialogModel();
31 | dialogModel.setType(selectType);
32 | popWin.bindData(dialogModel, new KeyBoardDialog.SelectCallBack() {
33 | @Override
34 | public void selectByType(int type, double value) {
35 | if (type == KeyBoardCenterDialog.TYPE_DIVISION && value == 0.0) {
36 | Toast.makeText(context, "不能除以0,请重新输入", Toast.LENGTH_SHORT).show();
37 | return;
38 | }
39 | int startColumn = selectRange[0];
40 | int startRow = selectRange[1];
41 | int endColumn = selectRange[2];
42 | int endRow = selectRange[3];
43 | //针对数据进行批量处理
44 | for (int i = 0; i < dataList.size(); i++) {
45 | if (i < startRow || i > endRow) {
46 | continue;
47 | }
48 | for (int j = startColumn; j <= endColumn; j++) {
49 | Double old = dataList.get(i).get(j);
50 | Double newValue = 0.0;
51 | switch (type) {
52 | case KeyBoardCenterDialog.TYPE_ADD:
53 | newValue = old + value;
54 | break;
55 | case KeyBoardCenterDialog.TYPE_SUB:
56 | newValue = old - value;
57 | break;
58 | case KeyBoardCenterDialog.TYPE_MULTI:
59 | newValue = old * value;
60 | break;
61 | case KeyBoardCenterDialog.TYPE_DIVISION:
62 | newValue = old / value;
63 | break;
64 | case KeyBoardCenterDialog.TYPE_ASSIGN:
65 | newValue = value;
66 | }
67 | dataList.get(i).set(j, newValue);
68 | }
69 | }
70 | excelView.notifyDataColor(selectRange, Color.RED);
71 | excelView.notifyDataChange(tableModel);
72 | }
73 | });
74 | //显示的坐标位置不一样
75 | popWin.showAtLocation(excelView, Gravity.CENTER, 0, 500);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/java/com/xt/excelview/util/IOHelper.java:
--------------------------------------------------------------------------------
1 | package com.xt.excelview.util;
2 |
3 | import java.io.File;
4 | import java.io.FileOutputStream;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import java.io.OutputStream;
8 |
9 | public class IOHelper {
10 | public static void copyFileFromInputStream(InputStream input,
11 | File dest)
12 | throws IOException {
13 | OutputStream output = null;
14 | try {
15 | output = new FileOutputStream(dest);
16 | byte[] buf = new byte[1024];
17 | int bytesRead;
18 | while ((bytesRead = input.read(buf)) != -1) {
19 | output.write(buf, 0, bytesRead);
20 | }
21 | } finally {
22 | input.close();
23 | output.close();
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
19 |
20 |
26 |
27 |
33 |
34 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_first.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
21 |
22 |
33 |
34 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_haha.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_second.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_third.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
26 |
27 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 样式1打开
4 | 样式2打开
5 | 读取xls格式文件
6 | 读取xlsx格式文件
7 | 保存
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 16dp
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ExcelDemo
3 | Settings
4 |
5 | First Fragment
6 | Second Fragment
7 | Next
8 | Previous
9 |
10 | Hello first fragment
11 | Hello second fragment. Arg: %1$s
12 |
13 |
14 | open Style1
15 | open Style2
16 | open xls file
17 | open xlsx file
18 | Save
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | // mavenLocal()
5 | google()
6 | mavenCentral()
7 | }
8 | dependencies {
9 | classpath "com.android.tools.build:gradle:7.0.3"
10 |
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | // mavenLocal()
19 | google()
20 | mavenCentral()
21 | }
22 | /*todo fix:
23 | 防止-Xlint:unchecked 重新编译。错误*/
24 | gradle.projectsEvaluated {
25 | tasks.withType(JavaCompile) {
26 | options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
27 | // Try to turn them all off automatically
28 | options.compilerArgs << '-Xlint:none'
29 | options.compilerArgs << '-nowarn' // same as '-Xlint:none'
30 |
31 | // Turn them off manually
32 | options.compilerArgs << '-Xlint:-auxiliaryclass'
33 | options.compilerArgs << '-Xlint:-cast'
34 | options.compilerArgs << '-Xlint:-classfile'
35 | options.compilerArgs << '-Xlint:-deprecation'
36 | options.compilerArgs << '-Xlint:-dep-ann'
37 | options.compilerArgs << '-Xlint:-divzero'
38 | options.compilerArgs << '-Xlint:-empty'
39 | options.compilerArgs << '-Xlint:-fallthrough'
40 | options.compilerArgs << '-Xlint:-finally'
41 | options.compilerArgs << '-Xlint:-options'
42 | options.compilerArgs << '-Xlint:-overloads'
43 | options.compilerArgs << '-Xlint:-overrides'
44 | options.compilerArgs << '-Xlint:-path'
45 | options.compilerArgs << '-Xlint:-processing'
46 | options.compilerArgs << '-Xlint:-rawtypes'
47 | options.compilerArgs << '-Xlint:-serial'
48 | options.compilerArgs << '-Xlint:-static'
49 | options.compilerArgs << '-Xlint:-try'
50 | options.compilerArgs << '-Xlint:-unchecked'
51 | options.compilerArgs << '-Xlint:-varargs'
52 | }
53 | }
54 | /*todo fix :
55 | 忽略java编译时的警告*/
56 | tasks.withType(JavaCompile) {
57 | configure(options) {
58 | incremental = true
59 | }
60 | // options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
61 | options.encoding = "UTF-8"
62 | }
63 | configurations {
64 | all*.exclude group: 'com.android.support', module: 'support-compat'
65 | all*.exclude group: 'com.android.support', module: 'support-v4'
66 | all*.exclude group: 'com.android.support', module: 'support-annotations'
67 | all*.exclude group: 'com.android.support', module: 'support-fragment'
68 | all*.exclude group: 'com.android.support', module: 'support-core-utils'
69 | all*.exclude group: 'com.android.support', module: 'support-core-ui'
70 | }
71 | tasks.withType(Javadoc) {
72 | options.addStringOption('Xdoclint:none', '-quiet')
73 | options.addStringOption('encoding', 'UTF-8')
74 | }
75 | }
76 |
77 | task clean(type: Delete) {
78 | delete rootProject.buildDir
79 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
--------------------------------------------------------------------------------
/pics/img/desc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/pics/img/desc.png
--------------------------------------------------------------------------------
/pics/img/drag.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/pics/img/drag.gif
--------------------------------------------------------------------------------
/pics/img/edit.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/pics/img/edit.gif
--------------------------------------------------------------------------------
/pics/img/rangselect.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/pics/img/rangselect.gif
--------------------------------------------------------------------------------
/pics/img/unrangselect.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/pics/img/unrangselect.gif
--------------------------------------------------------------------------------
/pics/mp4/drag.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/pics/mp4/drag.mp4
--------------------------------------------------------------------------------
/pics/mp4/edit.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/pics/mp4/edit.mp4
--------------------------------------------------------------------------------
/pics/mp4/rangeselect.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/pics/mp4/rangeselect.mp4
--------------------------------------------------------------------------------
/pics/mp4/unselectrange.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/pics/mp4/unselectrange.mp4
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | }
4 |
5 | android {
6 | compileSdk 31
7 |
8 | defaultConfig {
9 | applicationId "com.xt.excelview.sample"
10 | minSdk 26
11 | targetSdk 31
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | compileOptions {
25 | sourceCompatibility JavaVersion.VERSION_1_8
26 | targetCompatibility JavaVersion.VERSION_1_8
27 | }
28 | buildFeatures {
29 | viewBinding true
30 | }
31 | }
32 |
33 | dependencies {
34 |
35 | implementation 'androidx.appcompat:appcompat:1.2.0'
36 | implementation 'com.google.android.material:material:1.3.0'
37 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
38 | implementation 'androidx.navigation:navigation-fragment:2.3.5'
39 | implementation 'androidx.navigation:navigation-ui:2.3.5'
40 | // testImplementation 'junit:junit:4.+'
41 | // androidTestImplementation 'androidx.test.ext:junit:1.1.2'
42 | // androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
43 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.0"
44 | // implementation project(':ExcelViewLib')
45 | // implementation project(':PoiLib')
46 | implementation 'io.github.september26:excelview:0.9.4'
47 | implementation 'io.github.september26:excelview-poi:0.9.4'
48 | }
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
17 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/sample/src/main/assets/demo.xls:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/sample/src/main/assets/demo.xls
--------------------------------------------------------------------------------
/sample/src/main/assets/demo.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/sample/src/main/assets/demo.xlsx
--------------------------------------------------------------------------------
/sample/src/main/java/com/xt/excelview/Fragment1.java:
--------------------------------------------------------------------------------
1 | package com.xt.excelview;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import androidx.annotation.NonNull;
9 | import androidx.annotation.Nullable;
10 | import androidx.fragment.app.Fragment;
11 |
12 | import com.xt.excelview.databinding.FragmentFirstBinding;
13 | import com.xt.excelview.lib.control.ExcelControlInter;
14 | import com.xt.excelview.lib.control.ExcelControlImpl;
15 | import com.xt.excelview.lib.view.ExcelView;
16 |
17 | import java.math.BigDecimal;
18 | import java.util.ArrayList;
19 |
20 | /**
21 | * demo1样例
22 | * 直接使用ExcelControlImpl以及其中的逻辑
23 | *
24 | * @author lxl
25 | */
26 | public class Fragment1 extends Fragment {
27 |
28 | private FragmentFirstBinding binding;
29 |
30 | @Override
31 | public View onCreateView(
32 | LayoutInflater inflater, ViewGroup container,
33 | Bundle savedInstanceState
34 | ) {
35 |
36 | binding = FragmentFirstBinding.inflate(inflater, container, false);
37 | return binding.getRoot();
38 | }
39 |
40 | @Override
41 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
42 | super.onViewCreated(view, savedInstanceState);
43 | ExcelControlInter control = new ExcelControlImpl(binding.excelView, binding.scrollX, binding.scrollY, null);
44 | ExcelView.TableValueModel tableValueModel = getModel();
45 | //进行绑定
46 | control.bindData(tableValueModel);
47 | }
48 |
49 | @Override
50 | public void onDestroyView() {
51 | super.onDestroyView();
52 | binding = null;
53 | }
54 |
55 | public ExcelView.TableValueModel getModel() {
56 | ExcelView.TableValueModel model = new ExcelView.TableValueModel();
57 | model.columnTitle = "纵向标题";
58 | model.rowTitle = "横向标题";
59 | model.onlyReadXNum = 2;
60 | model.onlyReadYNum = 1;
61 |
62 | //横向,纵向都设置为30格
63 | int size = 30;
64 | for (int i = 1; i < size; i++) {
65 | ArrayList strings = new ArrayList<>();
66 | for (int j = 1; j < size; j++) {
67 | strings.add(new BigDecimal(i + (double) j / 100.0).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
68 | }
69 | model.dataList.add(strings);
70 | }
71 | model.rows = model.dataList.size();
72 | model.columns = model.dataList.get(0).size();
73 | return model;
74 | }
75 |
76 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/xt/excelview/Fragment2.java:
--------------------------------------------------------------------------------
1 | package com.xt.excelview;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import androidx.annotation.NonNull;
9 | import androidx.fragment.app.Fragment;
10 |
11 | import com.xt.excelview.custom.CustomControlImpl;
12 | import com.xt.excelview.databinding.FragmentSecondBinding;
13 | import com.xt.excelview.lib.control.ExcelControlInter;
14 | import com.xt.excelview.lib.view.ExcelView;
15 |
16 | import java.math.BigDecimal;
17 | import java.util.ArrayList;
18 |
19 | public class Fragment2 extends Fragment {
20 |
21 | private FragmentSecondBinding binding;
22 |
23 | @Override
24 | public View onCreateView(
25 | LayoutInflater inflater, ViewGroup container,
26 | Bundle savedInstanceState
27 | ) {
28 | binding = FragmentSecondBinding.inflate(inflater, container, false);
29 | return binding.getRoot();
30 | }
31 |
32 | public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
33 | super.onViewCreated(view, savedInstanceState);
34 | ExcelControlInter control = new CustomControlImpl(binding.excelView, null);
35 | ExcelView.TableValueModel tableValueModel = getModel();
36 | //进行绑定
37 | control.bindData(tableValueModel);
38 | }
39 |
40 | @Override
41 | public void onDestroyView() {
42 | super.onDestroyView();
43 | binding = null;
44 | }
45 |
46 | public ExcelView.TableValueModel getModel() {
47 | ExcelView.TableValueModel model = new ExcelView.TableValueModel();
48 | model.columnTitle = "纵向标题";
49 | model.rowTitle = "横向标题";
50 | model.onlyReadXNum = 2;
51 | model.onlyReadYNum = 1;
52 |
53 | //横向,纵向都设置为30格
54 | int size = 30;
55 | for (int i = 1; i < size; i++) {
56 | ArrayList strings = new ArrayList<>();
57 | for (int j = 1; j < size; j++) {
58 | strings.add(new BigDecimal(i + (double) j / 100.0).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
59 | }
60 | model.dataList.add(strings);
61 | }
62 | model.rows = model.dataList.size();
63 | model.columns = model.dataList.get(0).size();
64 | return model;
65 | }
66 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/xt/excelview/Fragment3.java:
--------------------------------------------------------------------------------
1 | package com.xt.excelview;
2 |
3 | import android.os.Bundle;
4 | import android.util.Log;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.annotation.Nullable;
11 | import androidx.fragment.app.Fragment;
12 |
13 | import com.xt.excelview.custom.CustomControlImpl;
14 | import com.xt.excelview.databinding.FragmentThirdBinding;
15 | import com.xt.excelview.util.IOHelper;
16 | import com.xt.excelview.lib.control.ExcelControlInter;
17 | import com.xt.excelview.lib.view.ExcelView;
18 | import com.xt.excelview.poi.poi.PoiUtil;
19 |
20 | import java.io.File;
21 | import java.io.IOException;
22 | import java.io.InputStream;
23 |
24 | public class Fragment3 extends Fragment {
25 |
26 | private FragmentThirdBinding binding;
27 | private final String FILE_NAME = "demo";
28 | private String FILE_PATH;
29 |
30 | @Override
31 | public void onCreate(@Nullable Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | FILE_PATH = getActivity().getFilesDir().getAbsolutePath() + File.separator;
34 | }
35 |
36 | @Override
37 | public View onCreateView(
38 | LayoutInflater inflater, ViewGroup container,
39 | Bundle savedInstanceState
40 | ) {
41 | binding = FragmentThirdBinding.inflate(inflater, container, false);
42 | return binding.getRoot();
43 | }
44 |
45 | public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
46 | super.onViewCreated(view, savedInstanceState);
47 | //拷贝文件到data/file目录下,然后跳转
48 | Bundle arguments = getArguments();
49 | String type = "xls";
50 | if (arguments != null) {
51 | type = arguments.getString("type");
52 | }
53 | String fileName = FILE_NAME + "." + type;
54 | String filePath = FILE_PATH + fileName;
55 | File file = new File(filePath);
56 | if (!file.exists()) {
57 | try {
58 | InputStream open = getActivity().getAssets().open(fileName);
59 | IOHelper.copyFileFromInputStream(open, file);
60 | } catch (IOException e) {
61 | e.printStackTrace();
62 | }
63 | }
64 | showExcel(file, filePath);
65 | }
66 |
67 | private void showExcel(File file, String filePath) {
68 | ExcelControlInter control = new CustomControlImpl(binding.excelView, null);
69 | ExcelView.TableValueModel model = PoiUtil.readExcel(file);
70 | Log.i("lxltest", "model:" + model.dataList.size());
71 | //进行绑定
72 | control.bindData(model);
73 |
74 | binding.buttonSave.setOnClickListener(v -> {
75 | //很对model生成
76 | PoiUtil.write2Excel(filePath, model);
77 | });
78 | }
79 |
80 | @Override
81 | public void onDestroyView() {
82 | super.onDestroyView();
83 | binding = null;
84 | }
85 |
86 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/xt/excelview/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.xt.excelview;
2 |
3 | import android.os.Bundle;
4 |
5 | import androidx.appcompat.app.AppCompatActivity;
6 | import androidx.fragment.app.Fragment;
7 | import androidx.fragment.app.FragmentTransaction;
8 |
9 | import com.xt.excelview.databinding.ActivityMainBinding;
10 |
11 |
12 | public class MainActivity extends AppCompatActivity {
13 |
14 | private ActivityMainBinding binding;
15 | private Fragment1 firstFragment;
16 | private Fragment2 secondFragment;
17 | private Fragment3 thirdFragment;
18 | private int REQUEST_CODE = 1;
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | binding = ActivityMainBinding.inflate(getLayoutInflater());
24 | setContentView(binding.getRoot());
25 |
26 |
27 | binding.buttonFirst.setOnClickListener(v -> {
28 | if (firstFragment == null) {
29 | firstFragment = new Fragment1();
30 | }
31 | showFragment(firstFragment);
32 | });
33 |
34 | binding.buttonSecond.setOnClickListener(v -> {
35 | if (secondFragment == null) {
36 | secondFragment = new Fragment2();
37 | }
38 | showFragment(secondFragment);
39 | });
40 |
41 | binding.buttonThird.setOnClickListener(v -> {
42 | if (thirdFragment == null) {
43 | thirdFragment = new Fragment3();
44 | }
45 | Bundle bundle = new Bundle();
46 | bundle.putString("type", "xls");
47 | thirdFragment.setArguments(bundle);
48 | showFragment(thirdFragment);
49 | });
50 |
51 | binding.buttonFourth.setOnClickListener(v -> {
52 | if (thirdFragment == null) {
53 | thirdFragment = new Fragment3();
54 | }
55 | Bundle bundle = new Bundle();
56 | bundle.putString("type", "xlsx");
57 | thirdFragment.setArguments(bundle);
58 | showFragment(thirdFragment);
59 | });
60 | }
61 |
62 | private void showFragment(Fragment fragment) {
63 | FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
64 | if (!fragment.isAdded()) {
65 | fragmentTransaction.add(android.R.id.content, fragment);
66 | fragmentTransaction.addToBackStack(null);
67 | fragmentTransaction.commit();
68 | } else {
69 | fragmentTransaction.show(fragment);
70 | }
71 | }
72 |
73 | // private void requestPermission(Context context) {
74 | // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
75 | // // 先判断有没有权限
76 | // if (Environment.isExternalStorageManager()) {
77 | // readFile();
78 | // } else {
79 | // Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
80 | // intent.setData(Uri.parse("package:" + context.getPackageName()));
81 | // startActivityForResult(intent, REQUEST_CODE);
82 | // }
83 | // } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
84 | // // 先判断有没有权限
85 | // if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
86 | // ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
87 | // readFile();
88 | // } else {
89 | // ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
90 | // }
91 | // } else {
92 | // readFile();
93 | // }
94 | // }
95 | //
96 | // public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
97 | // super.onRequestPermissionsResult(requestCode, permissions, grantResults);
98 | // if (requestCode == REQUEST_CODE) {
99 | // if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
100 | // ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
101 | // readFile();
102 | // } else {
103 | // Toast.makeText(this, "存储权限获取失败", Toast.LENGTH_LONG).show();
104 | // }
105 | // }
106 | // }
107 | //
108 | // protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
109 | // super.onActivityResult(requestCode, resultCode, data);
110 | // if (requestCode == REQUEST_CODE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
111 | // if (Environment.isExternalStorageManager()) {
112 | // readFile();
113 | // } else {
114 | // Toast.makeText(this, "存储权限获取失败", Toast.LENGTH_LONG).show();
115 | // }
116 | // }
117 | // }
118 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/xt/excelview/custom/CustomControlImpl.java:
--------------------------------------------------------------------------------
1 | package com.xt.excelview.custom;
2 |
3 | import android.graphics.Color;
4 | import android.view.Gravity;
5 | import android.view.View;
6 | import android.widget.Toast;
7 |
8 | import com.xt.excelview.lib.control.ExcelControlImpl;
9 | import com.xt.excelview.lib.dialog.KeyBoardCenterDialog;
10 | import com.xt.excelview.lib.dialog.KeyBoardDialog;
11 | import com.xt.excelview.lib.util.DeviceUtil;
12 | import com.xt.excelview.lib.view.ExcelView;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * 开发者自定义
18 | */
19 | public class CustomControlImpl extends ExcelControlImpl {
20 |
21 | public CustomControlImpl(ExcelView excelView, View.OnClickListener listener) {
22 | super(excelView, listener);
23 | }
24 |
25 | @Override
26 | public void showKeyboard(ExcelView.TableValueModel tableModel, int[] selectRange, int selectType) {
27 | //这里使用KeyBoardCenterDialog替换原来的KeyBoardDialog,从而实现不一样的显示效果
28 | List> dataList = tableModel.dataList;
29 | KeyBoardCenterDialog popWin = new KeyBoardCenterDialog(context, DeviceUtil.getScreenSize(context)[0], dipUnit * 137);
30 | KeyBoardDialog.DialogModel dialogModel = new KeyBoardDialog.DialogModel();
31 | dialogModel.setType(selectType);
32 | popWin.bindData(dialogModel, new KeyBoardDialog.SelectCallBack() {
33 | @Override
34 | public void selectByType(int type, double value) {
35 | if (type == KeyBoardCenterDialog.TYPE_DIVISION && value == 0.0) {
36 | Toast.makeText(context, "不能除以0,请重新输入", Toast.LENGTH_SHORT).show();
37 | return;
38 | }
39 | int startColumn = selectRange[0];
40 | int startRow = selectRange[1];
41 | int endColumn = selectRange[2];
42 | int endRow = selectRange[3];
43 | //针对数据进行批量处理
44 | for (int i = 0; i < dataList.size(); i++) {
45 | if (i < startRow || i > endRow) {
46 | continue;
47 | }
48 | for (int j = startColumn; j <= endColumn; j++) {
49 | Double old = dataList.get(i).get(j);
50 | Double newValue = 0.0;
51 | switch (type) {
52 | case KeyBoardCenterDialog.TYPE_ADD:
53 | newValue = old + value;
54 | break;
55 | case KeyBoardCenterDialog.TYPE_SUB:
56 | newValue = old - value;
57 | break;
58 | case KeyBoardCenterDialog.TYPE_MULTI:
59 | newValue = old * value;
60 | break;
61 | case KeyBoardCenterDialog.TYPE_DIVISION:
62 | newValue = old / value;
63 | break;
64 | case KeyBoardCenterDialog.TYPE_ASSIGN:
65 | newValue = value;
66 | }
67 | dataList.get(i).set(j, newValue);
68 | }
69 | }
70 | excelView.notifyDataColor(selectRange, Color.RED);
71 | excelView.notifyDataChange(tableModel);
72 | }
73 | });
74 | //显示的坐标位置不一样
75 | popWin.showAtLocation(excelView, Gravity.CENTER, 0, 500);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/xt/excelview/util/IOHelper.java:
--------------------------------------------------------------------------------
1 | package com.xt.excelview.util;
2 |
3 | import java.io.File;
4 | import java.io.FileOutputStream;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import java.io.OutputStream;
8 |
9 | public class IOHelper {
10 | public static void copyFileFromInputStream(InputStream input,
11 | File dest)
12 | throws IOException {
13 | OutputStream output = null;
14 | try {
15 | output = new FileOutputStream(dest);
16 | byte[] buf = new byte[1024];
17 | int bytesRead;
18 | while ((bytesRead = input.read(buf)) != -1) {
19 | output.write(buf, 0, bytesRead);
20 | }
21 | } finally {
22 | input.close();
23 | output.close();
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/sample/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
19 |
20 |
26 |
27 |
33 |
34 |
40 |
41 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/fragment_first.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
21 |
22 |
33 |
34 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/fragment_haha.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/fragment_second.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/fragment_third.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
26 |
27 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/sample/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/sample/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/sample/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/sample/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/sample/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/sample/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/sample/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/September26/ExcelView/522a6fedc174d6eebbcd3d28640702ca11272005/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/sample/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 样式1打开
4 | 样式2打开
5 | 读取xls格式文件
6 | 读取xlsx格式文件
7 | 保存
8 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 16dp
3 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ExcelDemo
3 | Settings
4 |
5 | First Fragment
6 | Second Fragment
7 | Next
8 | Previous
9 |
10 | Hello first fragment
11 | Hello second fragment. Arg: %1$s
12 |
13 |
14 | open Style1
15 | open Style2
16 | open xls file
17 | open xlsx file
18 | Save
19 |
20 |
21 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = "ExcelView"
2 | include ':app'
3 | include ':sample'
4 | include ':ExcelViewLib'
5 | include ':PoiLib'
6 |
--------------------------------------------------------------------------------