java poi *** 作xlsx文件,如何在原xlsx上进行某一行的复制到当前xlsx的新增行,内容和样式和原行保持不变

java poi *** 作xlsx文件,如何在原xlsx上进行某一行的复制到当前xlsx的新增行,内容和样式和原行保持不变,第1张

首先要读取xlsx文件,创建一个基于硬盘的FileItem工厂  ,DiskFileItemFactory

用poi读文件内容,获取到表格的行,不知道有没有直接复制某行的方法,但最笨的方法,可以读取每一个单元格,再新增一行,将数据一次插入

HSSFSheet sheet = workbookgetSheetAt(0);先创建一个sheet对象

HSSFRow row =sheetgetRow(0);以第一行为例

short  lenth=rowgetLastCellNum() ; 获取列数

遍历列 ,用rowgetCell() 获取列值

创建新行  HSSFRow newRow = sheetcreateRow(sheetgetLastRowNum()+1);

再遍历赋值  HSSFCell cell = newRowcreateCell(i);

之前只做过poi的导入导出,所以没有实测,你可以尝试一下

按列读取的方法:

String pathname = "E:\\files\\titlexlsx";

File file = new File(pathname);

InputStream in = new FileInputStream(file);

//得到整个excel对象

XSSFWorkbook excel = new XSSFWorkbook(in);

//获取整个excel有多少个sheet

int sheets = excelgetNumberOfSheets();

//便利第一个sheet

Map<String,String> colMap = new HashMap<String, String>();

for(int i = 0 ; i < sheets ; i++ ){

XSSFSheet sheet = excelgetSheetAt(i);

if(sheet == null){

continue;

}

int mergedRegions = sheetgetNumMergedRegions();

XSSFRow row2 = sheetgetRow(0);

Map<Integer,String> category = new HashMap<Integer, String>();

for(int j = 0 ; j < mergedRegions; j++ ){

CellRangeAddress rangeAddress = sheetgetMergedRegion(j);

int firstRow = rangeAddressgetFirstColumn();

int lastRow = rangeAddressgetLastColumn();

categoryput(rangeAddressgetFirstColumn(), rangeAddressgetLastColumn()+"-"+row2getCell(firstRow)toString());

}

//便利每一行

for( int rowNum = 1 ; rowNum <= sheetgetLastRowNum() ; rowNum++ ){

Systemoutprintln();

XSSFRow row = sheetgetRow(rowNum);

if(row == null){

continue;

}

short lastCellNum = rowgetLastCellNum();

String cate = "";

Integer maxIndex = 0;

for( int col = rowgetFirstCellNum() ; col < lastCellNum ; col++ ){

XSSFCell cell = rowgetCell(col);

if(cell == null ){

continue;

}

if(""equals(celltoString())){

continue;

}

int columnIndex = cellgetColumnIndex();

String string = categoryget(columnIndex);

if(string != null && !stringequals("")){

String[] split = stringsplit("-");

cate = split[1];

maxIndex = IntegerparseInt(split[0]);

Systemoutprintln(cate+"<-->"+celltoString());

}else {

//如果当前便利的列编号小于等于合并单元格的结束,说明分类还是上面的分类名称

if(columnIndex<=maxIndex){

Systemoutprintln(cate+"<-->"+celltoString());

}else {

Systemoutprintln("分类未知"+"<-->"+celltoString());

}

}

}

}

}

}

一、excel读取的两种方式

Java中解析excel的方式,我目前知道的有两种,一种是 jxl 读取,另一种是 poi 读取

11 jxl 和 poi 的区别和选择

① jxl 只能解析 xls 文件,不能 解析 xlsx 文件; poi 则是可以同时兼容xls 和xlsx两种文件类型,这是要注意的第一个点;

② 这两个方法的读取方式不一样,jxl 读取的是 先读列 然后循环获取的该列每行的信息。poi 读取是 先读行,再循环获取每列的信息。如下图:

一般就用POI、JXL

但是JXL2011年后好像就没更新了,不支持Office2007后的xlsx文件

所以大多数都在用POI

两者使用大同小异,都一样简单,找个Demo就能熟悉

若因限制不能使用POI(平台冲突等)是否需要考虑回头用JXL?那要看你能否接受只支持office2007的 xls文件

Excel的两种导出入门方法(JAVA与JS)

最近在做一个小项目作为练手,其中使用到了导出到Excel表格,一开始做的是使用JAVA的POI导出的,但因为我的数据是爬虫爬出来的,数据暂时并不保存在数据库或后台,所以直接显示在HTML的table,需要下载时又要将数据传回后台然后生成Excel文件,最后再从服务器下载到本地,过程几度经过网络传输,感觉比较耗时与浪费性能,于是想着在HTML中的Table直接导到Excel中节约资源

JAVA导出EXCEL(xls)

导出Excel用的插件是apache的poijar,maven地址如下

<dependency>

<groupId>orgapachepoi</groupId>

<artifactId>poi</artifactId>

<version>317</version></dependency>

1 简单应用

先来个简化无样式的Excel导出,由于我的数据存在JSON中,所以形参是JSONArray,朋友们根据自己的实际数据类型(Map,List,Set等)传入即可 ,代码如下

/

创建excel并填入数据

@author LiQuanhui

@date 2017年11月24日 下午5:25:13

@param head 数据头

@param body 主体数据

@return HSSFWorkbook

/

public static HSSFWorkbook expExcel(JSONArray head, JSONArray body) {        //创建一个excel工作簿

HSSFWorkbook workbook = new HSSFWorkbook();        //创建一个sheet工作表

HSSFSheet sheet = workbookcreateSheet("学生信息");

//创建第0行表头,再在这行里在创建单元格,并赋值

HSSFRow row = sheetcreateRow(0);

HSSFCell cell = null;        for (int i = 0; i < headsize(); i++) {

cell = rowcreateCell(i);

cellsetCellValue(headgetString(i));//设置值

}

//将主体数据填入Excel中

for (int i = 0, isize = bodysize(); i < isize; i++) {

row = sheetcreateRow(i + 1);

JSONArray stuInfo = bodygetJSONArray(i);            for (int j = 0, jsize = stuInfosize(); j < jsize; j++) {

cell = rowcreateCell(j);

cellsetCellValue(stuInfogetString(j));//设置值

}

}        return workbook;

}

创建好Excel对象并填好值后(就是得到workbook),就是将这个对象以文件流的形式输出到本地上去,代码如下

/

文件输出

@author LiQuanhui

@date 2017年11月24日 下午5:26:23

@param workbook 填充好的workbook

@param path 存放的位置

/

public static void outFile(HSSFWorkbook workbook,String path) {

OutputStream os=null;        try {

os = new FileOutputStream(new File(path));

workbookwrite(os);

} catch (FileNotFoundException e1) {

e1printStackTrace();

} catch (IOException e) {

eprintStackTrace();

}        try {

osclose();

} catch (IOException e) {

eprintStackTrace();

}

}

至此Excel的导出其实已经做完了。

2 添加样式后导出

但通常这并不能满足我们的需求,因为通常是需要设置Excel的一些样式的,如字体、居中等等,设置单元格样式主要用到这个类(HSSFCellStyle)

HSSFCellStyle cellStyle = workbookcreateCellStyle();

现在说说HSSFCellStyle都能干些什么

HSSFCellStyle cellStyle = workbookcreateCellStyle();//创建单元格样式对象1设置字体

HSSFFont font = workbookcreateFont();  //fontsetFontHeight((short)12);//这个设置字体会很大

fontsetFontHeightInPoints((short)12);//这才是我们平常在Excel设置字体的值

fontsetFontName("黑体");//字体:宋体、华文行楷等等

cellStylesetFont(font);//将该字体设置进去2设置对齐方式

cellStylesetAlignment(horizontalAlignment);//horizontalAlignment参考下面给出的参数

//以下是最常用的三种对齐分别是居中,居左,居右,其余的写代码的时候按提示工具查看即可

HorizontalAlignmentCENTER

HorizontalAlignmentLEFT

HorizontalAlignmentRIGHT3设置边框

cellStylesetBorderBottom(border); // 下边框

cellStylesetBorderLeft(border);// 左边框

cellStylesetBorderTop(border);// 上边框

cellStylesetBorderRight(border);// 右边框

//border的常用参数如下

BorderStyleNONE 无边框

BorderStyleTHIN 细边框

BorderStyleMEDIUM 中等粗边框

BorderStyleTHICK 粗边框//其余的我也描述不清是什么形状,有兴趣的到时可以直接测试

在经过一系列的添加样式之后,最后就会给单元格设置样式

cellsetCellStyle(cellStyle);

3 自动调整列宽

sheetautoSizeColumn(i);//i为第几列,需要全文都单元格居中的话,需要遍历所有的列数

4 完整的案例

public class ExcelUtils {    /

创建excel并填入数据

@author LiQuanhui

@date 2017年11月24日 下午5:25:13

@param head 数据头

@param body 主体数据

@return HSSFWorkbook

/

public static HSSFWorkbook expExcel(JSONArray head, JSONArray body) {

HSSFWorkbook workbook = new HSSFWorkbook();

HSSFSheet sheet = workbookcreateSheet("学生信息");

HSSFRow row = sheetcreateRow(0);

HSSFCell cell = null;

HSSFCellStyle cellStyle = workbookcreateCellStyle();

setBorderStyle(cellStyle, BorderStyleTHIN);

cellStylesetFont(setFontStyle(workbook, "黑体", (short) 14));

cellStylesetAlignment(HorizontalAlignmentCENTER);

for (int i = 0; i < headsize(); i++) {

cell = rowcreateCell(i);

cellsetCellValue(headgetString(i));

cellsetCellStyle(cellStyle);

}

HSSFCellStyle cellStyle2 = workbookcreateCellStyle();

setBorderStyle(cellStyle2, BorderStyleTHIN);

cellStyle2setFont(setFontStyle(workbook, "宋体", (short) 12));

cellStyle2setAlignment(HorizontalAlignmentCENTER);        for (int i = 0, isize = bodysize(); i < isize; i++) {

row = sheetcreateRow(i + 1);

JSONArray stuInfo = bodygetJSONArray(i);            for (int j = 0, jsize = stuInfosize(); j < jsize; j++) {

cell = rowcreateCell(j);

cellsetCellValue(stuInfogetString(j));

cellsetCellStyle(cellStyle2);

}

}        for (int i = 0, isize = headsize(); i < isize; i++) {

sheetautoSizeColumn(i);

}        return workbook;

}    /

文件输出

@author LiQuanhui

@date 2017年11月24日 下午5:26:23

@param workbook 填充好的workbook

@param path 存放的位置

/

public static void outFile(HSSFWorkbook workbook,String path) {

OutputStream os=null;        try {

os = new FileOutputStream(new File(path));

workbookwrite(os);

} catch (FileNotFoundException e1) {

e1printStackTrace();

} catch (IOException e) {

eprintStackTrace();

}        try {

osclose();

} catch (IOException e) {

eprintStackTrace();

}

}    /

设置字体样式

@author LiQuanhui

@date 2017年11月24日 下午3:27:03

@param workbook 工作簿

@param name 字体类型

@param height 字体大小

@return HSSFFont

/

private static HSSFFont setFontStyle(HSSFWorkbook workbook, String name, short height) {

HSSFFont font = workbookcreateFont();

fontsetFontHeightInPoints(height);

fontsetFontName(name);        return font;

}    /

设置单元格样式

@author LiQuanhui

@date 2017年11月24日 下午3:26:24

@param workbook 工作簿

@param border border样式

/

private static void setBorderStyle(HSSFCellStyle cellStyle, BorderStyle border) {

cellStylesetBorderBottom(border); // 下边框

cellStylesetBorderLeft(border);// 左边框

cellStylesetBorderTop(border);// 上边框

cellStylesetBorderRight(border);// 右边框

}

}

POI的功能其实还是很强大的,这里只介绍了Excel的一丁点皮毛给入门的查看,如果想对Excel进行更多的设置可以查看下面的这篇文章,有着大量的使用说明。

空谷幽澜的POI使用详解

JS导出EXCEL(xls)

java的Excel导出提供了强大的功能,但也对服务器造成了一定资源消耗,若能使用客户端的资源那真是太好了

1 简单应用

JS的导出Excel非常简单,只需要引用Jquery和tableExportjs并设置一个属性即可

<script src="<%=basePath%>/static/js/tableExportjs" type="text/javascript"></script><script type="text/javascript">

function exportExcelWithJS(){    //获取要导出Excel的表格对象并设置tableExport方法,设置导出类型type为excel

$('#tableId')tableExport({      type:'excel'

});

}</script><button class="btn btn-primary"  type="button" style="float: right;" onclick="exportExcelWithJS()">下载本表格</button>

JS的导出就完成了,是不是特别简单

2 进阶应用

但上面仅仅是个简单的全表无样式的导出

这tableExportjs还有一些其他功能,忽略行,忽略列,设置样式等,属性如下

<script type="text/javascript">

function exportExcelWithJS(){    //获取要导出Excel的表格对象并设置tableExport方法,设置导出类型type为excel

$('#tableId')tableExport({      type:'excel',//导出为excel

fileName:'2017工资表',//文件名

worksheetName:'11月工资',//sheet表的名字

ignoreColumn:[0,1,2],//忽略的列,从0开始算

ignoreRow:[2,4,5],//忽略的行,从0开始算

excelstyles:['text-align']//使用样式,不用填值只写属性,值读取的是html中的

});

}</script>

如上既是JS的进阶导出, *** 作简单,容易上手

但有个弊端就是分页的情况下,只能导出分页出的数据,毕竟这就是导出HTML内TABLE有的东西,数据在数据库或后台的也就无能为力,所以这个适合的是无分页的TABLE导出

3 额外说明

tableExportjs是gitHub上的hhurz大牛的一个开源项目,需要下载该JS的可以点击链接进入gitHub下载或在我的百度网盘下载 密码:oafu

tableExportjs不仅仅是个导出Excel的JS,他还可以导出CSV、DOC、JSON、PDF、PNG、SQL、TSV、TXT、XLS (Excel 2000 HTML format)、XLSX (Excel 2007 Office Open XML format)、XML (Excel 2003 XML Spreadsheet format)、XML (Raw xml)多种格式,具体使用可以参考hhurz的使用介绍

本人在之前找了好几个导出Excel的都有各种各样的问题(乱码,无响应,无样式),这个是目前找到最好的一个了,能解决乱码问题,能有样式,非常强大

近日来,研究了一下Excel Biff8(xls 97-2007)与OpenXML(ECMA-376)的加密文档的读取(这还是为了我们世界先进Grid而做的 ^__^)。有些成果,写在这里,希望能给要做类似功能的XD们一些参考。

如有不详,请联系:OwenLiu@GrapeCitycom / J2NETe@gmailcom

前提:

1 加密文档:指Wookbook级的加密,就是在Save Excel文档时在General Settings中设置open password之后的文档;

2 打开:需要用户传入密码。并非破解。但请勿将本文方法添加暴力模块使用 :-) ;

3 本文涉及较多为,密钥计算,关于解密细节请参考微软相关文档;

使用的加密算法: RC4, SHA1, MD5, AES-128(其中RC4并不包含在所有版本的NET Framework中,AES算法可以在NET Framework 35中找到)

本文示例依赖 NET Framework 35

A Biff8 的加密文档读取

1 通过文档中FILEPASS的record取得,文档的加密信息(关于Biff文档的格式问题,请参阅Biff的微软文档)

其中Biff8可以使用两种方法加密:Biff8标准加密算法和Biff8扩充加密算法。本文主要讨论最常用的Biff标准加密算法

2 通过FILEPASS的结构,获得如下信息:

salt(加密随机数,16 bytes)

password verifier (密码效验器,16 bytes)

password verifier hash(密码效验器Hash,16 bytes)

3 通过以上信息,生成解密key。并通过密码效验器,验证密码:

i 将密码转化成unicode数组,并进行MD5 Hash;

ii 将hash结果与salt串联,然后将byte数组,反复串联16次(336 bytes) ,然后再进行MD5 Hash;

iii 将上步hash结果的前五位,串联上4 bytes的block值(在密码验证阶段为0,在以后解密阶段为block的index) ,然后进行MD5 Hash;

iv 将上步hash结果的前16位,作为key

v 使用RC4对称加密算法,将password verifier和password verifier hash分别解密,然后对password verifier的解密结果进行MD5 hash,其值应和password verifier hash的解密结果一致,即为密码正确。

vi 之后进行逐个record的解密。excel biff8加密原则基本为,record的标示不加密,长度不加密,个别record不加密(见文档);另外,在record解密时,还需要通过block的值重新计算解密key,block的大小为1024

4 详细请参照示例代码;

B OpenXML(ECMA-376) 加密文档的读取

1 通常来说,xlsx文件相当于一个zip文件,可以用zip程序,直接打开。而在加密后,为了安全性考虑,微软使用了 structured storage(一种OLE文档存储方式)存储(可以用7-zip或者OLE document viewer打开,windows也有相应API来 *** 作此类结构)。在上述文档中,有一个叫做“EncryptedPackage”加密的package,就是一个zip包通过AES算法进行加密之后的结果。我们将使用和A一样的方式来检查密码,但生成key的方法不同;OpenXML的加密类型也有多种,我们这里就讨论常用的用AES-128进行加密的流程;

2 通过文档的“EncryptedInfo”部分,需要过的一下信息(关于此部分的结构,请参考[MS-OFFCRYPTO]pdf)

salt(加密随机数,16 bytes)

password verifier (密码效验器,16 bytes)

password verifier hash(密码效验器Hash,32 bytes)

3 通过以上信息,生成解密key。并通过密码效验器,验证密码:

i 首先,定义一个H函数,其有两个输入,内部使用SHA1算法将两个输入串联之后的结果hash返回;

ii 先将salt与password(password的unicode数组)进行H计算,h = H(salt, password) ;

iii然后设iterator为0x00000000,将其转为4byte的数组,然后进行H计算,h1 = H(iterator, h);

iv将上面的iterator递增一,然后再与h1进行H计算,h2 = H(iterator,h1),然后将这个递增和计算过程重复50000次,最后计算过的iterator为49999即可;

v 现在有计算结果h50000,将h50000再与0x00000000(4 byte数组)进行H计算,Hfinal = H(h50000, 0x00000000);

vi 生成一个64byte的数组,将每位都初始化成0x36,然后将这个数组与Hfinal异或;(关于这个地方,微软文档中写的有错误,按照原文的方法生成的key不正确,要不是文档的作者回信告诉我要使用这个法子,就算我想破头也想不出来啊 T__T)

vii将异或结果,进行SHA1 hash,结果的前16byte就是解密的key;

viii初始化AES算法,key长度为128,模式为ECB模式,Padding为none; 然后将password verifier 和password verifier hash分别解密;

ix password verifier 解密后的SHA1 hash结果应该与password verifier hash解密后的前20byte相同;

4 关于"EncryptedPackage" 的解密则更为简单,只许将“EncryptedPackage”读入,去除前8byte的size信息后,进行AES解密,即为未加密的标准openxml文档。

参考:

[MS-OFFCRYPTO]pdf

[MS-XLS]pdf

ECMA-376 standards

Reply by "winnow", 2008-09-10, 1:17

-----------------------------------------------------

总结一下, 关于这两种基于密码的加密方法, 基本上都是基于RFC2898 建议, 思想是这样:

输入是用户的密码:password, 输出是提供给加密函数的密钥:key

考虑安全, 需要使同样的password生成的key不一样, 这样用相同的password加密后的结果就无法比较 需要一个随机数salt

另外, 为了使暴力破解的代价增大, 考虑使用一个循环多次的过程, 需要循环次数:iteration_count

概念上, 生成方法为: 将password和salt进行某种运算, 配合一个Hash函数, 以某种方式循环iteration_count次, 在最后的结果里取一部分作为key输出

具体参照RFC2898中的建议方法PBKDF1和PBKDF2

这样, 用户输入的密码与一个随机数组合, 经过一定代价的运算, 就生成了可以供加密函数使用的密钥 使用这个密钥和一个加密函数, 就可以进行加密了

在应用中, 为了快速判断密码是否错误 生成一个随机数verifier, 用一个Hash函数计算verifier的hash值:verifier_hash, 分别加密verifier和verifier_hash并保存

解密的时候, 先分别解密出verifier和verifier_hash, 计算verifier的hash值, 与verifier_hash比较, 如果一致, 即说明密码正确

java 读取excel是吧 网上有很多示例代码的

基本上先是 从本地获取文件 然后 转成文件流然后解析成ArrayList 解析代码网上有 解析成ArryList之后么 就随便你按格式拼装了

以上就是关于java poi *** 作xlsx文件,如何在原xlsx上进行某一行的复制到当前xlsx的新增行,内容和样式和原行保持不变全部的内容,包括:java poi *** 作xlsx文件,如何在原xlsx上进行某一行的复制到当前xlsx的新增行,内容和样式和原行保持不变、Java POI读取Excel的时候怎么按列读取、怎么获取excel字符间列java等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9505851.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-29
下一篇2023-04-29

发表评论

登录后才能评论

评论列表(0条)

    保存