libxl库能无需环境依赖实现后台读写xlsx表格,可用于AHK操控浏览器等采集数据后,用libxl库后台把数据整理保存下来。

 

以下展示libxl库能实现的效果,将下图原始数据表,一键转换成下下图的正式表格

 

转换后的效果图

 

示例链接:

 

打卡记录转换.ahk

#Include %A_ScriptDir%/../Lib/libxl.ahk
SetWorkingDir %A_ScriptDir%
SetBatchLines -1
#MaxMem 256

libxl.init(A_ScriptDir "/../Lib/64bit/libxl.dll")  ; 初始化加载指定路径的libxl.dll

; 托盘
Gui, Destroy
Menu, Tray, NoStandard                  ;删除自带托盘菜单
Menu, tray, Add, 帮助, gcpy帮助                  ; 创建     
Menu, tray, Add, 关于, gcpy关于                  ; 创建   
Menu, tray, Add
Menu, tray, Add, 退出, gcpy退出                  ; 创建 

iii=
(
即将运行,请点击确定。。。。
作者:城西(3300372390) -2021-07-01
)
gui,+OwnDialogs
msgbox,% iii

;清空或定义变量
book :=""
book2 :=""
bzname :=""
arr :=[]	
bcxu :=0   ;表格数量序号
book2:=libxl.new("xlsx")  ; 新建工作簿用于保存新文件

loop Files,*.xlsx  ; 循环xlsx文件
{
  arr :=[]
  ; if A_LoopFileFullPath ~="^\~\$|^打卡记录转换文件_\d{6,}"  ; 打卡记录转换文件_ + 6位数字 的过滤
  if A_LoopFileFullPath ~="^\~\$|^打卡记录转换文件_"  ; 如果是隐藏的备份文件则跳过, 筛选的结果文件也过滤掉
    continue
  bcxu++  ;记录表序号
  book :=""
  book := libxl.Load(A_LoopFileFullPath)

  sheet :=book.active  ; 当前激活表
  xlsxlastRow :=sheet.lastRow()
  xlsxlastCol :=sheet.lastCol()
  bzname :=sheet.__Item[1,1].Value  ; 班主名字

  loop,% xlsxlastCol - 2  ;循环获取单元格数据
  {
    y :=A_Index
    loop,% xlsxlastRow - 1 
    {
      x :=A_Index
      try{
        arr[x,y]:=sheet.__Item[x,y+1].Value  ; 注意从姓名行列开始
        arr[x,y] := RegExReplace(arr[x,y],"_")
      }catch{
        arr[x,y]:=""
      }		

    }
  }

  ;写入新表
  newsheet%bcxu% :=book2.Addsheet(bcxu . bzname)  ;设置表序号加班组名字为表名

  ft1 :=book2.addFormat()  ; 居中+边框设置
  ft1.setBorder(1)  ; 设置边框
  ft1.setAlignH(2)  ; 设置水平居中
  ft1.setAlignV(1)  ; 设置竖直居中

  xx:=0
  yy:=1
  nit:=2  ; 坐标序号
  niy :=-1  ; 合并坐标序号
  xuhao1 :=0
  ;写入表头

  rs1 :=book2.addRichString()
  ff1 :=rs1.addFont()
  ff1.setSize(22)
  ff1.setBold(1)
  rs1.addText(bzname "  班组考勤表",ff1)
  newsheet%bcxu%.__Item[0,0] :=rs1  ; 写入班主名字
  ;newsheet%bcxu%.__Item[0,0] :=bzname "  班组考勤表"		;写入班主名字
  newsheet%bcxu%.__Item[1,0] := "序号"
  newsheet%bcxu%.__Item[1,1] := "姓名"
  newsheet%bcxu%.__Item[1,2] := "午别"
  loop,31
  {
    nit :=nit + 1
    newsheet%bcxu%.__Item[1,nit] := A_Index
  }
  newsheet%bcxu%.__Item[1,34] := "合计天数"
  newsheet%bcxu%.__Item[1,35] := "农民工签字"
  ; setMerge(rowFirst, rowLast, colFirst, colLast)
  newsheet%bcxu%.setMerge(0,0,0,35)
  loop,36
  {
    niy :=niy +1
    newsheet%bcxu%.setMerge(1,2,niy,niy)
    newsheet%bcxu%.SetCellFormat(0,niy,ft1)
    newsheet%bcxu%.SetCellFormat(1,niy,ft1)
    newsheet%bcxu%.SetCellFormat(2,niy,ft1)
  }
    newsheet%bcxu%.setCol(3,33,3)  ; 设置列宽
    newsheet%bcxu%.setCol(0,0,5)
    newsheet%bcxu%.setCol(34,34,9.5)
    newsheet%bcxu%.setCol(35,35,11)

  ; 写入数据
  loop,% xlsxlastRow - 1 
  {
    x :=A_Index
    xuhao1 :=A_Index
    xx:=xx+3
    loop,% xlsxlastCol - 2
    {
      y :=A_Index
      if y <> 1  ; 不是名字  则是时间,需正则处理
      {
        swd := RegExMatch(arr[x,y],"^.+\n") ? "√" : ""
        xwd := RegExMatch(arr[x,y],"\n.+$") ? "√" : ""

        newsheet%bcxu%.__Item[xx,y+1] :={value:swd,Format:ft1}
        newsheet%bcxu%.__Item[xx+1,y+1] :={value:xwd,Format:ft1}
        newsheet%bcxu%.__Item[xx+2,y+1] :={value:"",Format:ft1}
      }
      else
      {
        newsheet%bcxu%.__Item[xx,0] :=xuhao1  ; 写序号	
        newsheet%bcxu%.SetCellFormat(xx,0,ft1)
        newsheet%bcxu%.SetCellFormat(xx+1,0,ft1)
        newsheet%bcxu%.SetCellFormat(xx+2,0,ft1)
        newsheet%bcxu%.setMerge(xx,xx+2,0,0)	

        newsheet%bcxu%.__Item[xx,y] :={value:arr[x,y],Format:ft1}  ; 写姓名
        newsheet%bcxu%.__Item[xx+1,y] :={value:arr[x,y],Format:ft1}
        newsheet%bcxu%.__Item[xx+2,y] :={value:arr[x,y],Format:ft1}
        newsheet%bcxu%.setMerge(xx,xx+2,1,1)		
        
        newsheet%bcxu%.__Item[xx,y+1] :={value:"上午",Format:ft1}  ; 写午别
        newsheet%bcxu%.__Item[xx+1,y+1] :={value:"下午",Format:ft1}
        newsheet%bcxu%.__Item[xx+2,y+1] :={value:"加班",Format:ft1}
  
        js :=xuhao1 * 3 + 1  ; 写合计天数公式
        je :=js+2
        fom ==COUNTIF(D%js%:AH%je%,"=√")/2
        newsheet%bcxu%.writeFormula(xx,34,fom)
        newsheet%bcxu%.SetCellFormat(xx,34,ft1)
        newsheet%bcxu%.SetCellFormat(xx+1,34,ft1)
        newsheet%bcxu%.SetCellFormat(xx+2,34,ft1)
        newsheet%bcxu%.setMerge(xx,xx+2,34,34)		
        
        newsheet%bcxu%.SetCellFormat(xx,35,ft1)  ; 农民工签字格式
        newsheet%bcxu%.SetCellFormat(xx+1,35,ft1)
        newsheet%bcxu%.SetCellFormat(xx+2,35,ft1)
        newsheet%bcxu%.setMerge(xx,xx+2,35,35)								
      }
    }
  }
}

book2.save("打卡记录转换文件_" A_Now ".xlsx")
msgbox,完成
exitapp
return



tltip:
if actstate
{
  settimer,tltip,off
  ToolTip
  return
}
tltiptime++
ToolTip,请君骚等。。。%tltiptime%
return

goclear:
loop,5
{
  GuiControl,,guigjlz%A_Index%
  GuiControl,,guisxtj%A_Index%
}
Return

GuiEscape:
GuiClose:
gui,Destroy
return

gcpy帮助:
iii=
(
热键            :F12
关键列设置      :软件自动在表格前10行中找到匹配的列,作为关键列
筛选条件        :在对应关键列中筛选出匹配的行
读取表格设置     :-1>工作簿全部表格,0>工作簿中激活的表,1>工作簿中第一个表
清空            :清空设置的数据
不读取数据筛选   :在执行过一次后,且表格源数据不变的情况选择此项
)
gui,+OwnDialogs
msgbox,% iii
return


gcpy关于:  
iii=
(
名称:xls xlsx数据筛选工具
作者:城西(3300372390) -2021-3-27
)
gui,+OwnDialogs
msgbox,% iii
return

gcpy退出:
exitapp
return

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。