Android操作Excel文件的功能实现
Android中操作Excel文件导出报表时主要采用开源库jxl,最早用在java上,但也可用于Android。与之类似的POI,因为依赖库众多,所以只能用于java,而不能用于Android。
使用jxl需要在Android工程中导入jxl.jar包,jxl可以完成Excel的基本读写操作,其支持与不支持的情况如下:
1、jxl只支持Excel2003格式,不支持Excel2007格式。即支持xls文件,不支持xlsx文件。
2、jxl不支持直接修改excel文件,但可通过复制新文件覆盖原文件的方式来间接修改。
3、jxl只能识别PNG格式的图片,不能识别其他格式的图片。
上面可以看出,jxl不支持Excel2007,这个很不好,尤其是目前Excel2007已经成为Excel主流格式的时候。不过现在还有个实现Android读取2007格式的临时办法,如果我们仔细分析xlsx的文件格式,会发现xlsx文件其实是个压缩包,压缩包里有各种文件,其中数据一般是放在"xl/sharedStrings.xml"和"xl/worksheets/sheet1.xml"中。据此,我们判断Excel文件为2007格式时,便可以将其解压,然后从中提取出sharedStrings.xml和sheet1.xml,接着使用XML解析工具把具体数据解析出来。
下面是Excel文件的读写代码例子,其中支持2003格式的读和写,以及2007格式的读:
代码如下 | 复制代码 |
importjava.io.File;
importjava.io.IOException;
importjava.io.InputStream;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.zip.ZipEntry;
importjava.util.zip.ZipException;
importjava.util.zip.ZipFile;
importorg.xmlpull.v1.XmlPullParser;
importorg.xmlpull.v1.XmlPullParserException;
importandroid.util.Log;
importandroid.util.Xml;
importjxl.Sheet;
importjxl.Workbook;
importjxl.write.Label;
importjxl.write.WritableSheet;
importjxl.write.WritableWorkbook;
publicclassExcelUtil {
privatefinalstaticString TAG ="ExcelUtil"; publicstaticList<List
String extension = file_name.lastIndexOf(".") == -1?"": file_name
.substring(file_name.lastIndexOf(".") +1);
if("xls".equals(extension)) {// 2003
Log.d(TAG,"read2003XLS, extension:"+ extension);
returnread2003XLS(file_name);
}elseif("xlsx".equals(extension)) {
Log.d(TAG,"read2007XLSX, extension:"+ extension);
returnread2007XLSX(file_name);
}else{
Log.d(TAG,"不支持的文件类型, extension:"+ extension);
returnnull;
} } publicstaticList<List
List<List
try{
Workbook book = Workbook.getWorkbook(newFile(path));
// book.getNumberOfSheets(); //获取sheet页的数目
// 获得第一个工作表对象
Sheet sheet = book.getSheet(0);
intRows = sheet.getRows();
intCols = sheet.getColumns();
Log.d(TAG,"当前工作表的名字:"+ sheet.getName());
Log.d(TAG,"总行数:"+ Rows +", 总列数:"+ Cols); List
String val =null;
for(inti =0; i < Rows; i++) {
booleannull_row =true;
for(intj =0; j < Cols; j++) {
// getCell(Col,Row)获得单元格的值,注意getCell格式是先列后行,不是常见的先行后列
Log.d(TAG, (sheet.getCell(j, i)).getContents() +"\t");
val = (sheet.getCell(j, i)).getContents();
if(val ==null|| val.equals("")) {
val ="null";
}else{
null_row =false;
}
objList.add(val);
}
Log.d(TAG,"\n");
if(null_row !=true) {
dataList.add(objList);
null_row =true;
}
objList =newArrayList
}
book.close();
}catch(Exception e) {
Log.d(TAG, e.getMessage());
} returndataList;
} publicstaticList<List
List<List
String str_c ="";
String v =null;
booleanflat =false;
List
try{
ZipFile xlsxFile =newZipFile(newFile(path));
ZipEntry sharedStringXML = xlsxFile.getEntry("xl/sharedStrings.xml");
if(sharedStringXML ==null) {
Log.d(TAG,"空文件:"+ path);
returndataList;
}
InputStream inputStream = xlsxFile.getInputStream(sharedStringXML);
XmlPullParser xmlParser = Xml.newPullParser();
xmlParser.setInput(inputStream,"utf-8"); intevtType = xmlParser.getEventType();
while(evtType != XmlPullParser.END_DOCUMENT) {
switch(evtType) {
caseXmlPullParser.START_TAG:
String tag = xmlParser.getName();
if(tag.equalsIgnoreCase("t")) {
ls.add(xmlParser.nextText());
}
break;
caseXmlPullParser.END_TAG:
break;
default:
break;
}
evtType = xmlParser.next();
}
ZipEntry sheetXML = xlsxFile.getEntry("xl/worksheets/sheet1.xml");
InputStream inputStreamsheet = xlsxFile.getInputStream(sheetXML);
XmlPullParser xmlParsersheet = Xml.newPullParser();
xmlParsersheet.setInput(inputStreamsheet,"utf-8"); intevtTypesheet = xmlParsersheet.getEventType();
List
String val =null; booleannull_row =true; while(evtTypesheet != XmlPullParser.END_DOCUMENT) {
switch(evtTypesheet) {
caseXmlPullParser.START_TAG:
String tag = xmlParsersheet.getName();
if(tag.equalsIgnoreCase("row")) {
}elseif(tag.equalsIgnoreCase("c")) { String t = xmlParsersheet.getAttributeValue(null,"t");
if(t !=null) {
flat =true;// 字符串型
// Log.d(TAG, flat + "有");
}else{// 非字符串型,可能是整型
// Log.d(TAG, flat + "没有");
flat =false;
}
}elseif(tag.equalsIgnoreCase("v")) {
v = xmlParsersheet.nextText();
if(v !=null) {
if(flat) {
str_c += ls.get(Integer.parseInt(v)) +" ";
val = ls.get(Integer.parseInt(v));
null_row =false;
}else{
str_c += v +" ";
val = v;
}
objList.add(val);
}
}
break;
caseXmlPullParser.END_TAG:
if(xmlParsersheet.getName().equalsIgnoreCase("row") && v !=null) {
str_c +="\n";
if(null_row !=true) {
dataList.add(objList);
null_row =true;
} objList =newArrayList
} break; } evtTypesheet = xmlParsersheet.next();
} Log.d(TAG, str_c);
}catch(ZipException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}catch(XmlPullParserException e) {
e.printStackTrace();
} if(str_c ==null) {
str_c ="解析文件出现问题";
Log.d(TAG, str_c);
} returndataList;
} publicstaticintwriteExcel(String file_name, List<List
try{
WritableWorkbook book = Workbook.createWorkbook(newFile(file_name));
WritableSheet sheet1 = book.createSheet("sheet1",0);
for(inti =0; i < data_list.size(); i++) {
List
for(intj =0; j < obj_list.size(); j++) {
Label label =newLabel(j, i, obj_list.get(j).toString());
sheet1.addCell(label); } } book.write(); book.close();
}catch(Exception e) {
e.printStackTrace(); return-1; } return0; } |
本文介绍了Android清空编辑框内容功能的实现实例代码的教程,非常实用,有兴趣的同学可以参考一下本文
在项目开发中你肯定会遇到这样的需求,输入到EditText中的数据一个一个清理太麻烦了,需要有一个按钮直接能实现一次删除整个EditText控件中的数据,那么接下来我就给大家封装一个方法,有这样的需求直接调用就好了。话不多说,直接上代码:
代码如下 | 复制代码 |
/** *清空编辑框按钮 * @param editText 需要清空的EditText控件 * @param delImageView 清空数据的图片 */ protectedvoidclearEditText(finalEditText editText,finalImageView delImageView) { /文本框编辑的监听/ editText.addTextChangedListener(newTextWatcher() {
@Override publicvoidonTextChanged(CharSequence arg0,intarg1,intarg2,intarg3) { // TODO Auto-generated method stub
}
@Override publicvoidbeforeTextChanged(CharSequence arg0,intarg1,intarg2, intarg3) { // TODO Auto-generated method stub
}
@Override publicvoidafterTextChanged(Editable arg0) { // TODO Auto-generated method stub if(editText.getText().length()!=0){ delImageView.setVisibility(View.VISIBLE); }else{ delImageView.setVisibility(View.INVISIBLE); } } }); /**焦点变化监听**/ editText.setOnFocusChangeListener(newView.OnFocusChangeListener() { @Override publicvoidonFocusChange(View arg0,booleanarg1) { // TODO Auto-generated method stub if(editText.getText().length()!=0){ //删除图标显示 delImageView.setVisibility(View.VISIBLE); }else{ //删除图标隐藏 delImageView.setVisibility(View.INVISIBLE); } if(arg1){ //得到焦点 }else{ //失去焦点,删除图标隐藏 delImageView.setVisibility(View.INVISIBLE); } } }); //删除图标的点击监听事件 delImageView.setOnClickListener(newView.OnClickListener() {
@Override publicvoidonClick(View arg0) { // 执行清空EditText数据 editText.setText(""); } }); } |
结束,接下来根据需求在需要的地方进行调用就好。
Android O版本号到底是多少呢?Android O版本号确定为8.0。感兴趣的小伙伴们随小编进来看看吧现在对安卓系统下一个版本基本还是称呼为Android O,不过坊间已经将O这个代号和“奥利奥”对号入座了,不过有些认真的网友对其版本号非常执着,那么现在问题来了,Android O版本号到底是多少呢?
此前IDE工具曾有过相关暗示,称Android O版本号可能是7+,不过谷歌今天推出的最新Android O Beta3否认了前者的猜测,Android O的版本号为8.0。
现在只要更新了Android O Beta3,就可以在系统设置中“关于手机”界面查看得知,版本号显示为8.0,这样来看谷歌还是按照一年一个大版本更新的老习惯,因为去年主角是Android 7.0。
Android O带来了诸多重要更新,不过碎片化依然是头疼的老问题,谷歌即使最后推出正式版,估计还是有不少设备需要等待好几个时间,才能享受到最新固件。
本文介绍了android ViewPager实现滑动翻页效果实例代码,非常实用,有兴趣的同学可以参考一下
代码如下 | 复制代码 |
importandroid.content.Context; importandroid.support.v4.view.ViewPager; importandroid.util.AttributeSet; importandroid.view.View;
publicclassReadViewPagerextendsViewPager { publicReadViewPager(Context context) { super(context); }
publicReadViewPager(Context context, AttributeSet attrs) { super(context, attrs); setAnima(); }
publicvoidsetAnima() { setPageTransformer(true,newPageTransformer() { privatestaticfinalfloatMIN_SCALE =0.75f;
@Override publicvoidtransformPage(View view,floatposition) {
intpageWidth = view.getWidth(); intpageHeight =view.getHeight();
if(position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. view.setAlpha(0);
} elseif(position <=0) { // [-1,0] // Use the default slide transition when moving to the left page view.setAlpha(1); view.setTranslationX(0); view.setScaleX(1); view.setScaleY(1); } elseif(position <=1) { // (0,1]
// Fade the page out. view.setAlpha(1- position); // // // Counteract the default slide transition // view.setAlpha(1); view.setTranslationX(pageWidth * -position); // // // Scale the page down (between MIN_SCALE and 1) floatscaleFactor = MIN_SCALE + (1- MIN_SCALE) * (1- Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0); } }
}); } } |
核心代码是android官方demo,以上实现的是翻页效果是:上面一页被滑出界面时,下面一页慢慢显现,透明度慢慢加大,并且大小由小慢慢变大。
不过有一个奇怪的现象,当我做一个答题界面时,刚刚开始我采用ViewPager与View结合实现无限循环切换,并且采用上面的动画效果,可是每当我滑动到最后一张,也就是要开始新的一轮循环的时候,被滑出去的一页也会出现慢慢变透明的情况,而我用ViewPager结合Fragment实现无限循环切换的是就不会出现这种效果
如果想要实现仿造驾考宝典的翻页效果,只要把核心方法改为以下代码便可以了
代码如下 | 复制代码 |
setPageTransformer(true,newPageTransformer() { privatestaticfinalfloatMIN_SCALE =0.75f;
@Override publicvoidtransformPage(View view,floatposition) {
intpageWidth = view.getWidth(); intpageHeight =view.getHeight();
if(position < -1) {// [-Infinity,-1) // This page is way off-screen to the left. view.setAlpha(0);
}elseif(position <=0) {// [-1,0] // Use the default slide transition when moving to the left page view.setAlpha(1); view.setTranslationX(0); view.setScaleX(1); view.setScaleY(1);
}elseif(position <=1) {// (0,1]
// Fade the page out. // view.setAlpha(1 - position); // // // Counteract the default slide transition view.setAlpha(1); view.setTranslationX(pageWidth * -position); // // // Scale the page down (between MIN_SCALE and 1) // float scaleFactor = MIN_SCALE // + (1 - MIN_SCALE) * (1 - Math.abs(position)); // view.setScaleX(scaleFactor); // view.setScaleY(scaleFactor);
}else{// (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0); }
} }); |
下面我们来讲讲position参数:
position的可能性的值有:
[-Infinity,-1) 已经看不到了
(1,+Infinity] 已经看不到了
[-1,1]
重点看[-1,1]这个区间 , 其他两个的View都已经看不到了~~
假设现在ViewPager在A页现在滑出B页,则:
A页的position变化就是( 0, -1]
B页的position变化就是[ 1 , 0 ]
相关文章
- 下面小编来给大家演示几个php操作zip文件的实例,我们可以读取zip包中指定文件与删除zip包中指定文件,下面来给大这介绍一下。 从zip压缩文件中提取文件 代...2016-11-25
Jupyter Notebook读取csv文件出现的问题及解决
这篇文章主要介绍了JupyterNotebook读取csv文件出现的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2023-01-06- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
- 有时我们接受或下载到的PSD文件打开是空白的,那么我们要如何来解决这个 问题了,下面一聚教程小伙伴就为各位介绍Photoshop打开PSD文件空白解决办法。 1、如我们打开...2016-09-14
- 这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
- 这篇文章主要介绍了C#实现HTTP下载文件的方法,包括了HTTP通信的创建、本地文件的写入等,非常具有实用价值,需要的朋友可以参考下...2020-06-25
- 这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
- C#使用System.IO中的文件操作方法在Windows系统中处理本地文件相当顺手,这里我们还总结了在Oracle中保存文件的方法,嗯,接下来就来看看整理的C#操作本地文件及保存文件到数据库的基本方法总结...2020-06-25
php无刷新利用iframe实现页面无刷新上传文件(1/2)
利用form表单的target属性和iframe 一、上传文件的一个php教程方法。 该方法接受一个$file参数,该参数为从客户端获取的$_files变量,返回重新命名后的文件名,如果上传失...2016-11-25Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- 要替换字符串中的内容我们只要利用php相关函数,如strstr,str_replace,正则表达式了,那么我们要替换目录所有文件的内容就需要先遍历目录再打开文件再利用上面讲的函数替...2016-11-25
- 如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
- 又码了一个周末的代码,这次在做一些关于文件上传的东西。(PHP UPLOAD)小有收获项目是一个BT种子列表,用户有权限上传自己的种子,然后配合BT TRACK服务器把种子的信息写出来...2016-11-25
- 夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
- 为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
- 步骤:Window -> PHP -> Editor -> Templates,这里可以设置(增、删、改、导入等)管理你的模板。新建文件注释、函数注释、代码块等模板的实例新建模板,分别输入Name、Description、Patterna)文件注释Name: 3cfileDescriptio...2013-10-04
- 今天小编在这里就来给photoshop的这一款软件的使用者们来说下AI源文件转photoshop图像变模糊问题的解决教程,各位想知道具体解决方法的使用者们,那么下面就快来跟着小编...2016-09-14
- 这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
- 本篇文章主要说明的是与php文件上传的相关配置的知识点。PHP文件上传功能配置主要涉及php.ini配置文件中的upload_tmp_dir、upload_max_filesize、post_max_size等选项,下面一一说明。打开php.ini配置文件找到File Upl...2015-10-21
ant design中upload组件上传大文件,显示进度条进度的实例
这篇文章主要介绍了ant design中upload组件上传大文件,显示进度条进度的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-29