阅读(4580) (0)

anyline 工具类

2022-09-14 16:58:21 更新

1.AES加密解密

2.Base64Util

4.BeanUtil

递归提取对象中的value

以下JSON结构为例

{
    key1:{
      key11:{
          key111:111   //提取111 value(map,key1,key11, key111)
      },
      key12:{
          key121:{
              key1211:1211,
              key1212:1212 //提取1212 value(map,key1, key12, key121, key1212)
          }
      }
    }
}
BeanUtil提供以下函数
/ * 
* @param src 数据源
* @param voluntary 遇到基础类型是否停止(不取下一级)
*                  voluntary=false时遇到提取基础类型属性值时返回null
*                  voluntary=true时遇到提取基础类型属性值时返回当前value并return value
* @param keys keys 一级key.二级key.三级key
* @return Object
*/
public static Object extract(Object src, boolean voluntary, String ... keys);
 
BeanUtil.extract(json,"key1","key11","key111");//提取111 
//如果中途遇到基础类型,如key111的值是1111,但1111并没有key0属性
BeanUtil.extract(json,false,"key1","key11","key111","key0"); //返回null  
BeanUtil.extract(json,true,"key1","key11","key111","key0"); //遇到基础类型停止 直接返回1111  

8.DateUtil

关于日期类的链式操作

String ymd = DateBuilder.init().addYear(1).addDay(-1).format("yyyy-MM-dd");

9.DES加密解密

10.EscapeUtil

11.FileUtil

13.FTPUtil

16.HttpUtil

HttpUtil访问https的问题

HttpUtil访问https时报错,SunCertPathBuilderException:unable to find valid certification path to requested target
在web浏览器上(这里我用的是chrome)打开https的链接,然后点击https前面的小锁,然后点证书>详细信息>复制到文件.或点击view certificate.直接拖拽证书的图标到一个路径,保存下来,如果是自己的网站应该有证书文件直接复制一个就可以。
然后导入密钥库
在JAVA_HOME/jre/lib/securiy目录下执行 keytool -keystore cacerts -importcert -alias 别名 -file 上一步下载的文件,如果找不到keytool命令配置一下path

19.图片处理

关于生成水印位置偏移

WatermarkUtil实现水印添加
主要通过设置x,y坐标实现水印定位
默认以左上为(0,0)起始位置往右下偏移
如果设置xy为负数则从右下为(0,0)起始位置往左上偏移
xy默认为起始位置的偏移像素数量,

如果设置xy为小数则按长或宽的百分比计算偏移量如wihth=100,x=0.5则按左侧偏移50(100*0.5)像素

​WatermarkUtil util = new WatermarkUtil();​

在左上(10,10)生成水印

util.offset(10,10);

在距离右下边距(10,10)生成水印

util.offset(-10,-10);

在左上10%,10%生成水印

util.offset(0.1,0.1);

在距离右下边距(10%,10%)生成水印

util.offset(-0.1,-0.1);

生成水印并保存成新文件

util.makeIcon(iconFike, srcFile, dstFile);

生成水印并覆盖原文件

util.makeIcon(iconFike, srcFile);

指定水印长宽

util.makeIcon(iconFike, iconWidth, iconHeight,srcFile, dstFile);

22.MapUtil

23.MD5Util

24.MoneyUtil

26.NumberUtil

27.RSAUtil

29.SFTPUtil

30.SHA1Util

33.TextUtil

34.UrlUtil

35.验证码

36.水印

37.WebUtil

38.压缩工具

压缩文件

把item文件压缩到zip文件中
如果item是一个目录,则递归item中所有文件 
如果zip已存在则覆盖原文件
public static boolean zip(File item, File zip)
ZipUtil.zip(new File("D:\\users\\user.xml"), new File("D:\\user.zip"));
ZipUtil.zip(new File("D:\\users"), new File("D:\\user.zip"));
 
把item文件压缩到zip文件中的dir目录
public static boolean zip(File item, File zip, String dir)
public static boolean zip(Collection<file> items, File zip)
 
把items文件集合压缩到zip文件中,以key作为压缩目录
public static boolean zip(Map<string,file> items, File zip)
 
//替换zip压缩包中的item文件
public static void replace(File zip, File content, String item)
public static void replace(File zip, String content, String item)
 
//删除zip压缩包中的item文件
public static boolean remove(File zip, String item)
 
//读取zip压缩包中的item文件内容
public static InputStream read(File zip, String item)
public static String read(File zip, String item, String encode)
</string,file></file>

替换压缩包中的文件

//zip压缩包中的item文件替换成content文件
public static void replace(File zip, File content, String item)
//zip压缩包中的item文件替换成content内容
public static void replace(File zip, String content, String item)

向压缩文件中追加文件

public static boolean append(File item, File zip, String dir, String comment)
public static boolean append(File item, File zip)

39.LdapUtil

40. 视频工具

删除压缩包中的指定文件

删除zip中的item文件(含目录)
public static boolean remove(File zip, String item)
ZipUtil.remove(new File(”users.zip“),"user1.xml")
ZipUtil.remove(new File(”users.zip“),"list/user1.xml")

读取压缩包中的文件内容

//读取zip压缩包中的item文件内容
public static InputStream read(File zip, String item)
以String格式返回
public static String read(File zip, String item, String encode)

视频截图

视频截图需要依赖anyline-video

取第index帧截图

VideoUtil.frame(videoFile,imgFile,indx);

取中间帧截图

VideoUtil.frame(videoFile,imgFile);

41.TableBuilder

导出EXCEL中的序号

导出excel时如果每行需要一个序号可以用{num}来代替属性名,如
export(file,  list, "序号:{num}","姓名:NAME","年龄:AGE")

1张三20
2李四22
3王五25

导出EXCEL中的序号合并单元格

在导出excel时有可能不是每行一个序号,而是每组一个序号,如按部门分组,每个部门一个序号

1人事部张三20
张三三22
2财务部李四25
王五26

王五五

20

这时num需要部门列来合并单元格

TableBuilder builder = TableBuilder.init()
.setDatas(set)                          //设置数据源
.setFields("{num}(DEPARTMENT_NAME)"
            ,"DEPARTMENT_NAME"
            ,"USER_NAME"
            ,"USER_AGE")                //设置需要导出的属性(列)
.addUnion("DEPARTMENT_NAME");                   /设置需要合并行的列,如果年相同的合并,月相同的合并(前提是年相同)
File file = new File("模板地址");
ExcelUtil.export(file, "sheet名称", 2, builder.build()); //从第2行插入(根据表头行数)

设置所有合并单元格的对齐方式

TableBuilder.init()
.setMergeCellHorizontalAlign("center")  //设置合并单元格水平对齐方式
.setMergeCellVerticalAlign("center")    //设置合并单元格垂直对齐方式

设置指定列的对齐方式

TableBuilder.init()
.setHorizontalAlign("CHECK_CODE", "center")
.setVerticalAlign("CHECK_CODE", "top")

设置所有空值单元格对齐方式

有些情况下,需要把空值替换成其他固定的符号如(/)

这时可以设置这些单元格的对齐方式

TableBuilder.init()
.setEmptyCellVerticalAlign("top")
.setEmptyCellHorizontalAlign("center")

设置单元格默认边框

TableBuilder.init()..setCellBorder(true)

导出EXCEL合并单元格

数据是这样

模板是这样

导出后是这样

DataSet set = new DataSet();
 
DataRow row = new DataRow();
row.put("Y","2020");
row.put("M","1");
row.put("D","1");
set.add(row);
 
DataRow row2 = new DataRow();
row2.put("Y","2020");
row2.put("M","1");
row2.put("D","2");
set.add(row2);
 
DataRow row3 = new DataRow();
row3.put("Y","1999");
row3.put("M","1");
row3.put("D", null);
set.add(row3);
 
set.replaceEmpty("/");//替换空值的数据
 
TableBuilder builder = TableBuilder.init()
.setDatas(set)//设置数据源
.setFields("Y","M","D")//设置需要导出的属性(列)
.addUnion("Y","M(Y)");//设置需要合并行的列,如果年相同的合并,月相同的合并(前提是年相同)
File file = new File("模板地址");
ExcelUtil.export(file, "sheet名称", 2, builder.build()); //从第2行插入(根据表头行数)
 
System.out.println(builder.build().build()); //看一下输入对应的html

42. Excel操作

excel根据内容定位单元格

用户提交的excel内容经常不固定行列,而是需要根据单元格内容来确定表头位置或数据起止位置。

如根据内容中包含"结算日期"的单元格来确定当前行是表头,下一行是数据

根据内容中包含"会计年度"的单元格来确定当前数据年度。

int[] position = org.anyline.poi.excel.ExcelUtil.position(file.getInputStream(),"时间.*");

返回第1个包含"时间"的单元格位置(下标从0开始)

支持正则表达式,

可以根据返回的坐标来读取单元格内容

String value = ExcelUtil.value(File或InputStream, position[0], position[1]);

以上默认第0个Sheet页,可以指定Sheet下标或名称

读取带表头表尾的excel

File file = new File(dir,"template_102.xlsx");
ExcelReader reader = ExcelReader.init()
        .setFile(file)  //文件位置
        .setSheet(1)    //读取第1个sheet(下标从0开始)
        .setHead(0)     //表头在第0行,如果没有表头,结果集以下标作为key
        .setData(1)     //数据从第1行开始
        .setFoot(1)     //到第1行结束(如果负数表示 表尾有多少行不需要读取)
        ;
DataSet set = reader.read();
log.warn(set.toJSON());

导出复杂的表格需要借助TableBuilder先生成Table,再将Table导出到excel中

TableBuilder builder = TableBuilder.init()
        .setDatas(set)                                  //设置数据源
        .setFields(                                     //需要导出的列
                "{num}(EMPLOYEE_NM)"                    //{num}表示序号,(DEPARTMENT_NM)表示根据哪一列计算序号,这里部门名称需要分组合并,所以num不是按行计算
                ,"DEPARTMENT_NM"
                ,"EMPLOYEE_NM"
                ,"YM"
                ,"BASE_PRICE")
        .addUnion(                                      //需要合并的列
                "DEPARTMENT_NM"                         //如果部门名称相同则合并
                ,"EMPLOYEE_NM(DEPARTMENT_NM)"
                ,"YM(DEPARTMENT_NM)"                    //如果月份相同则合并,前提是部门已经合并
        )
        .setReplaceEmpty("/")                           //如果值为空则以/代替
        .addIgnoreUnionValue("/")                       //不参与合并的值
        .setCellBorder(true)                            //设置默认边框
        .setMergeCellHorizontalAlign("center")          //设置合并的列 水平对齐方式
        .setMergeCellVerticalAlign("top")               //设置合并的列 垂直对齐方式
        .setEmptyCellHorizontalAlign("center")          //设置空单元格 水平对齐方式(为空时有可能需要替换成其他值)
        .setEmptyCellVerticalAlign("top")               //设置空单元格 垂直对齐方式
        .setHorizontalAlign("YM","center")  //设置月份列 水平对齐方式
        .setVerticalAlign("middle")                     //设置所有数据单元格 垂直对齐方式
        .setLineHeight("50px")                          //设置数据区域行高
        .setWidth("YM","200px")             //设置月份列 宽度
        ;
Table table = builder.build();
File file = new File(dir, "export_table.xlsx");
ExcelUtil.export(file, table);

最简单的导出一个列表,如果文件已存在,则在原文件内容基础上插入行

DataSet set = service.querys("V_HR_SALARY","YYYY:"+ (DateUtil.year()-1), "ORDER BY EMPLOYEE_ID, YM");
//最简单的导出一个列表,如果文件已存在,则在原文件内容基础上插入行
File file = new File(dir,"export_list.xlsx");
//1表示从第1行插入,如果原来文件有内容,则下移
//{num}表示第几行,下标从1开始
//这里支持复合KEY
ExcelUtil.export(file,1, set,"序号:{num}","部门:DEPARTMENT_NM","姓名:EMPLOYEE_NM","月份:YM","底薪:{BASE_PRICE}+{REWARD_PRICE}");
 
//如果表头、表尾格式比较复杂,可先创建模板,再根据模板导出
File template = new File(dir,"template.xlsx");//这里是一个模板文件
//根据模板导出时就不需要指定表头了,只要对应好顺序,并计算好从哪一行开始写入
if(template.exists()) {
    ExcelUtil.export(template, file, 1, set, "{num}", "DEPARTMENT_NM", "EMPLOYEE_NM", "YM", "{BASE_PRICE}+{REWARD_PRICE}");
}

读取合并单元格的excel

File file = new File(dir,"export_table.xlsx");
List list = ExcelUtil.read(file);   //默认读取第0个sheet从第0行开始
list = ExcelUtil.read(file,1,3);    //读取第1个sheet从第3行读取
 
//遇到合并单元格的,将拆分开未合并前的状态,拆分后补上每个单元格的值
//返回的是一个二维数组
//为了操作方便可以把返回值转换成DataSet,DataSet中的条目(DataRow)以excel列下标作为属性key
DataSet set = new DataSet(list);

导出excel,多个sheet

//默认情况下导出的第0个sheet也就是sheet1
//如果要导出到多个sheet需要执行多次export导出到同一个文件,每次执行时指定sheet名称或下标
Table table = null;
File file = new File(dir, "export_sheet.xlsx");
ExcelUtil.export(file, "shet1", table);
ExcelUtil.export(file, "shet2", table);

往同一个excel中写多个sheet

public static boolean export(File file, String sheet, int rows, DataSet set, String ... configs)

如果文件存在则在当前文件中插入数据,如果文件不存在则新创建文件

这里的sheet如果在file中已存在,则往这个sheet中插入数据,如果不存在则新创建sheet再继续插入数据,其他重载函数规则相同。

File file = new File();
export(file, "s1",0, set, "ID"); //这一行执行完成后在文件中有一个sheet(s1)
export(file, "s2",0, set, "ID");//这一行执行完后文件中有两个sheet(s1,s2)

读取合并单元格的excel值


读取被合并行的单元格时,会从当前合并组中取第一个单元格的值

以上读取结果[[11, 12, 13], [21, 22, 23], [21, 32, 33]]

读取Excel

org.anyline.poi.excel.ExcelUtil提供了读取excel的工具,

file:需要读取的文件

sheet:需要读取的sheet名称或下标

rows:从第几行开始读取

返回二维List<List<String>>

public static List<List<String>> read(File file, int sheet, int rows)
public static List<List<String>> read(File file, int sheet) 
public static List<List<String>> read(File file)
public static List<List<String>> read(File file, String sheet, int rows) 
public static List<List<String>> read(File file, String sheet)

导出excel

导出excel两种情况:有模板或没有模板
如果没有模板直接导出一个新文件
如果有模板则在原模板基础上追加内容
如果模板文件中有多个sheet一般是先复制一个新文件,再以新文件作为输入参数调用多次没有模板参数的export()往新文件中的插入数据

/**
 * 导出EXCEL
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板
 * @param rows 开始写入的行数
 * @param headers 表头
 * @param keys 读取集合条目的属性
 * @param set 数据集合
 * @return boolean
 */
public static boolean export(File file, int rows, List<String>headers, List<String> keys, DataSet set) 
/**
 * 导出EXCEL
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板 
 * @param keys 读取集合条目的属性
 * @param set 数据集合
 * @return boolean
 */
public static boolean export(File file, List<String> keys, DataSet set) 
/**
 * 导出EXCEL
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板
 * @param headers 表头
 * @param keys 读取集合条目的属性
 * @param set 数据集合
 * @return boolean
 */
public static boolean export(File file, List<String> headers,List<String> keys, DataSet set) 
/**
 * 导出EXCEL
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板
 * @param rows 从第几行开始写入
 * @param keys 读取集合条目的属性
 * @param set 数据集合
 * @return boolean
 */
public static boolean export(File file, int rows, List<String> keys, DataSet set) 
 
/**
 * 导出excel
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板
 * @param sheet sheet 如果文件存在 并且为空时 则取第0个sheet
 * @param rows 行数
 * @param set 数据
 * @param configs 姓名:NAME或NAME
 * @return boolean
 */
public static boolean export(File file, String sheet, int rows, DataSet set, String ... configs) 
 
/**
 * 导出excel
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板
 * @param rows 行数
 * @param set 数据
 * @param configs 姓名:NAME或NAME
 * @return boolean
 */
public static boolean export(File file, int rows, DataSet set, String ... configs) 
 
/**
 * 导出excel
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板 
 * @param set 数据
 * @param configs 姓名:NAME或NAME
 * @return boolean
 */
public static boolean export(File file,  DataSet set, String ... configs)

以下需要有模板文件

/**
 * 导出EXCEL
 * @param template 模板
 * @param file 导致文件位置
 * @param headers   表头  headers 表头
 * @param sheet     sheet
 * @param insert        导出的开始位置
 * @param keys      对应列名属性名  keys       对应列名属性名
 * @param set       数据源  set        数据源
 * @return return
 */
public static boolean export(File template, File file, String sheet, int insert, List<String>headers, List<String> keys, DataSet set) 
/**
 * 导出EXCEL
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板
 * @param rows 开始写入的行数
 * @param headers 表头
 * @param keys 读取集合条目的属性
 * @param set 数据集合
 * @return boolean
 */
public static boolean export(File template, File file, int rows, List<String>headers, List<String> keys, DataSet set) 
/**
 * 导出EXCEL
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板
 * @param keys 读取集合条目的属性
 * @param set 数据集合
 * @return boolean
 */
public static boolean export(File template, File file, List<String> keys, DataSet set) 
/**
 * 导出EXCEL
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板
 * @param headers 表头
 * @param keys 读取集合条目的属性
 * @param set 数据集合
 * @return boolean
 */
public static boolean export(File template, File file, List<String> headers,List<String> keys, DataSet set) 
 
/**
 * 导出EXCEL
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板
 * @param rows 从第几行开始写入
 * @param keys 读取集合条目的属性
 * @param set 数据集合
 * @return boolean
 */
public static boolean export(File template, File file, int rows, List<String> keys, DataSet set) 
/**
 * 导出excel
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板
 * @param sheet sheet 如果文件存在 并且为空时 则取第0个sheet
 * @param rows 行数
 * @param set 数据
 * @param configs 姓名:NAME或NAME
 * @return boolean
 */
public static boolean export(File template, File file, String sheet, int rows, DataSet set, String ... configs) 
 
/**
 * 导出excel
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板
 * @param rows 行数
 * @param set 数据
 * @param configs 姓名:NAME或NAME
 * @return boolean
 */
public static boolean export(File template, File file, int rows, DataSet set, String ... configs) 
 
/**
 * 导出excel
 * @param file 导致文件位置,如果文件已存存,则以当前文件作为模板
 * @param set 数据
 * @param configs 姓名:NAME或NAME
 * @return boolean
 */
public static boolean export(File template, File file,  DataSet set, String ... configs)

43. 正则表达式

html代码中抽取指定标签

//获取所有超链接(a标签)
        /*
         * 提取单标签+双标签
         * 不区分大小写
         * 0:全文 1:开始标签 2:标签name 3:标签体 (单标签时null) 4:结束标签 (单标签时null)
         * 注意标签体有可能是HTML片段,而不是纯文本
         */
        List<List<String>> list = RegularUtil.fetchAllTag(html,"a");
        log.warn("标签数量:"+list.size());
        for(List<String> item:list){
            log.warn("全文:"+item.get(0));
            log.warn("开始标签:"+item.get(1));
            log.warn("标签名称:"+item.get(2));
            log.warn("标签体:"+item.get(3));
            log.warn("结束标签:"+item.get(4));
        }
 
        //抽取所有 a标签和li标签
        //一定注意:这里的a有可能被包含在li内部,这时的a不会再抽取
        list = RegularUtil.fetchAllTag(html,"a","li");

html中抽取标签时嵌套问题

从html中抽取多个标签,如需要抽取a标签和li标签

最简单的是抽取两次

RegularUtil.fetchAllTag(html,"a")

RegularUtil.fetchAllTag(html,"li")

但这样有个问题,两个标签的顺序会乱,

如果需要保持顺序可以通过

RegularUtil.fetchAllTag(html,"a","li");

但是一定注意:这里的a有可能被包含在li内部,这时li中的a不会再单独抽取

从html源码中截取字符串

//放多情况下我们并不需要复杂的标签内容,只需要截取几个关键字
//如提取商品名称和商品价格,而这两个值有可能是根其他内容混在一块的
//如以下这段源码
String html ="<div class='title' data-product='1001'>商品名称(限时)</div>"
+"<div class='price'>一个货币符号:100.00</div>";
//这时可以通过字符串截取的方式提取出价格
//第0个参数:源数据
//第1个到倒数第2个参数:100.00(就是我们要提取的价格) 之前出现的关键字
//最后1个参数:100.00之后出现的第1个关键字
 
//参数顺序:  源码,k1,k2,k3,kn-1,内容,kn
 
String price = RegularUtil.cut(html, "price",":","</div>");
log.warn("价格:{}",price);
 
//许多情况下price有可能在源码中出现多次,这时需要多个关键字的组合来确认100.00的位置
 
html = DateUtil.format("yyyy-MM-dd")+ "<div class='title' data-product='1001'>商品名称(限时)</div>" +
        "div class='src-price price'></div>" +
        "<div class='price'>一个货币符号:100.00</div>元";
 
price = RegularUtil.cut(html,"src-price","price", "price",":","</div>");
log.warn("价格:{}",price);
 
//如果需要提取的内容在最后 如上面的单位:元
String unit = RegularUtil.cut(html,"src-price","price", "price",":","</div>", RegularUtil.TAG_END);
log.warn("单位:{}", unit);
 
//同样的如果需要提取的内容在最开始位置 如上面的日期
 
String ymd = RegularUtil.cut(html, RegularUtil.TAG_BEGIN, "<");
log.warn("日期:{}", ymd);

44. Word操作