文档章节

Log4j2高级配置以及简单的示例

吕兵阳
 吕兵阳
发布于 2016/08/18 12:02
字数 3722
阅读 2636
收藏 10
点赞 3
评论 6

前言

  Appender按网络释义,有“输出目的地”之意。官网给出的定义是:“Appenders are responsible for delivering LogEvents to their destination.”。Log4j2为使用者提供了13种非常实用的Appenders,使用者可用方便的调用这13种Appender来控制日志的输出。

摘要

  Log4j2的Appenders充分考虑了日志事件的输出、包装以及过滤转发的可能,包括最基本的输出到本地文件、输出到远程主机,对文件进行封装、注入,并且还能按照日志文件的时间点、文件大小等条件进行自动封存。例如,想要将几个不同源的日志汇集到一起,可以用FlumeAppender;想要在LogEvent中注入信息,可以用RewriteAppender;想要让系统按照设定的时间间隔自动封存日志信息,可以用RollingFileAppender(每隔一定时间自动保存一份新增的日志文件,并按照时间戳等指定格式命名);当产生安全级别达ERROR或FATAL的LogEvent时,给维护人员发送邮件可用SMTPAppender;希望将日志信息写到远程主机的,可用SocketAppender;希望能够按照RFC5424格式向远程主机发送日志信息,可用SyslogAppender。等等。

下面将按照如下顺序依次介绍每个Appender的作用及重要参数,并附上完整参数地址及官网配置示例地址。

目录

1、FileAppender   普通地输出到本地文件

2、FlumeAppender  将几个不同源的日志汇集、集中到一处。

3、JMSQueueAppender VS. JMSTopicAppender  与JMS相关的日志输出

4、RewriteAppender   对日志事件进行掩码或注入信息

5、RollingFileAppender  对日志文件进行封存(详细)

6、RoutingAppender  在输出地之间进行筛选路由

7、SMTPAppender  将LogEvent发送到指定邮件列表

8、SocketAppender  将LogEvent以普通格式发送到远程主机

9、SyslogAppender  将LogEvent以RFC 5424格式发送到远程主机

10、AsynchAppender   将一个LogEvent异步地写入多个不同输出地

11、ConsoleAppender  将LogEvent输出到命令行

12、FailoverAppender  维护一个队列,系统将尝试向队列中的Appender依次输出LogEvent,直到有一个成功为止

正文:

1、FileAppender

FileAppender用于将LogEvent写入到一个文件中,该文件由fileName参数指定。有几个重要的参数:

fileName,String,指定写入的log文件的名称。

append,boolean,指定是否是追加写入(append=true,默认情况),还是覆盖写入(append=false)。

bufferedIO,boolean,是否对数据进行缓冲到缓冲区满后再写入。测试显示,即使在启用immediateFlush的情况下,设置bufferedIO=true也能提高性能。

locking,boolean,是否对文件上锁,当有多个线程可能同时写该文件时需要考虑上锁(在《异常处理反模式》中就提到要把在一起的日志输出语句写到一句,而不是拆成几句来避免并发线程导致的日志语句之间的错位)。但对文件上锁会影响系统的性能,所以需要谨慎使用。默认值是false。

完整的参数设置和官方配置示例

2、FlumeAppender

   FlumeAppender是一个可选的组件,它并不包含在core jar中,若要使用,需要额外加入log4j-flume-ng-2.0-beta4.jar包。FlumeAppender是配合Apache Flume来使用的。Apache Flume是一个能有效地将不同地方的大量日志数据收集、聚会到一起的一个系统。详细信息参见【Apache Flume

几个比较重要的参数:

agents,Agent[],用来维护一个将接收log event的数组,如果数组中agent的数量大于1,那么将把第一个agent视为primary agent,剩下的为备选agent。当第一个agent无法连接时,将把log event发送给备选agent。

batchSize,integer,一次给agent发送的log event的个数。

compress,boolean,当设置为true时,发送的message将使用gzip进行压缩。

完整的参数设置和官方配置示例

3、JMSQueueAppender VS. JMSTopicAppender

  JMSQueueAppender的作用是将格式化的log event发送到JMSQueue上,同样的,JMSTopicAppender的作用是将格式化的log event发送到JMSTopic上。JMSQueue和JMSTopic的区别是,JMSQueue只将一个message发送给一个consumer,而JMSTopic是将一个message发布(publish)给所有订阅了这个message的订阅者(subscribe)。更详细的两者间的区别可以【戳这里

几个重要的参数:

JMSQueueAppender:

queueBindingName,String, 用来定位queue。

factoryBindingName,String, 用来定位产生上下文信息的QueueConnectionFactory

完整的参数设置和官方配置示例

JMSTopicAppender:

topicBindingName,String, 用来定位topic。

factoryBindingName,String, 用来定位产生上下文信息的QueueConnectionFactory

完整的参数设置和官方配置示例

4、RewriteAppender

  RewriteAppender可以让符合筛选条件的log event在被其他appender输出前被加工一下,比如对message中的密码进行掩码,或者向message中注入信息等。RewriteAppender需要一个RewritePolicy来指定重写的规则。

几个重要的参数:

appender-ref,String,指定被重写后的log event将发往哪个appender。

rewritePolicy,RewritePolciy,用来描述重写log event的规则。

RewritePolicy:

RewritePolicy是一个接口,有一个需要实现的方法名为rewrite,该方法接收一个log event对象作为参数,然后经过函数处理后返回该log event或新建一个log event返回。

Log4j2中已实现的两种RewritePolicy有MapRewritePolicy和PropertiesRewritePolicy。

完整的参数设置、已实现的RewritePolicy和官方配置示例

5、RollingFileAppender

  RollingFileAppender是一个非常有意思的输出器。它将log信息写入一个文件后,会判断是否满足封存文件的要求,若满足,则除非封存文件的动作。RollingFileAppender需要TriggeringPolicy来指定触发封存的条件,另外还需要RolloverStrategy来告诉输出器如何封存文件。

Log4j2中已提供的TriggeringPolicy有如下四种:

CompositeTriggeringPolicy

复合型触发策略。即将多个触发条件逻辑或到一起,只要其中一个条件满足,则触发封存动作。

OnStartup Triggering Policy

这一触发策略不需要参数设置,它会自行判断log文件的创建时间和JVM的启动时间。若log文件的创建时间早于JVM的启动时间,则将原来的log文件封存,然后创建一个新的空白log文件。

SizeBased Triggering Policy

这一触发策略基于对log文件大小的判断。当log文件大于设定的阈值时,将触发封存动作。可设定的log文件大小的单位有bytes、KB、MB或GB。

TimeBased Triggering Policy

基于时间的触发策略。该策略主要是完成周期性的log文件封存工作。有两个参数:

interval,integer型,指定两次封存动作之间的时间间隔。

modulate,boolean型,说明是否对封存时间进行调制。若modulate=true,则封存时间将以0点为边界进行偏移计算。比如,modulate=true,interval=4hours,那么假设上次封存日志的时间为03:00,则下次封存日志的时间为04:00,之后的封存时间依次为08:00,12:00,16:00,。。。

Log4j2中实现的RolloverStrategy为Default Rollover Strategy,它有三个参数可以设置,分别为:

fileIndex,String,有两个选择“max”或“min”。设置为“max”意味着将最新的日志信息封存在序号较大的封存文件中。“min”则相反。

min,integer,封存文件的序号的起始值。

max,integer,封存文件的序号的最大值。(超过最大值时,将有文件被删除)

相当于min和max两个参数设置了一个保存窗口,超出这个窗口的日志文件将会被删除。

完整的参数设置、TriggeringPolicy和RolloverStrategy的用法示例

6、RoutingAppender

  通过路由规则来评价一个log event后,决定它下一个被发往的appender。RoutingAppender有一个重要的参数名为routes,是Routes型数据,用来描述该appender的路由规则。

完整的参数设置和官方配置示例

7、SMTPAppender

  SMTPAppender主要用来给指定的E-mail发送log event(这种情况一般用在event的安全级别超过ERROR或FATAL时,event的安全分级可以参考【此文】之日志记录小节)。SMTPAppender有很多重要的参数以完成log event发送到指定E-mail。

bcc,String,由逗号分隔的几个盲抄送地址。(盲抄送就是说收件人的地址不会显示在邮件信息中

cc,String,由逗号分隔的几个明抄送地址。(明抄送就是说收件人的地址将显示在邮件信息中

bufferSize,integer,信中所能包含的最大log event的数量。

from,String,发件人的地址。

layout,Layout,log event的布局格式。默认为SerializedLayout。

replyTo,String,回信的地址。

smtpHost,String,要发送到的SMTP的主机名。(此参数是必需的)

smtpPassword,String,通过SMTP服务器所需的密码。

smtpPort,integer,SMTP服务的端口号。

smtpProtocol,String,使用的协议。默认为"smtp"。

其他还有smtpUsername(通过SMTP server所需的用户名),to(接收者的邮件地址)等。

完整的参数介绍和官方配置示例

8、SocketAppender

将log event输出到一个远程服务器上(需指定服务器名和端口号),数据可以以任意指定的格式经由TCP或UDP协议发送。

SocketAppender中比较重要的参数有:

host,String,指定服务器的主机名。(必需)

immediateFlush,boolean,是否立即flush,还是等待缓存到一定大小后在flush。

layout,Layout,log event输出的格式。

port,integer,远程服务器坚挺log event的应用的端口号。

protocol,String,发送log event所使用的协议,"TCP" 或"UDP"。

reconnectionDelay,integer,当连接断开时,延迟等待的ms数。

完整的参数介绍和官方配置示例

9、SyslogAppender

SyslogAppender跟SocketAppender一样,是将log event发送到远程服务器上,但是使用的是BSD Syslog格式。关于Syslog格式可以【戳这里

完整的参数介绍和官方配置示例

10、AsynchAppender   

  将一个LogEvent异步地写入多个不同输出地。在AsynchAppender中有一个参数,名为“appender-ref”,用来指定要发送到的appender的名称。AsynchAppender维护了一个队列,队列中存放了需要异步发送的LogEvent,队列中LogEvent的个数可以通过“bufferSize”参数来指定。另外,还有一个“blocking”参数来指定是否对AsynchAppender的LogEvent队列上锁,如果blocking=true,那么在队列满员的情况下,新到达的LogEvent将等待,直到有空位。若blocking=false,那么在队列满员的情况下,将把新到的LogEvent转到error appender。

完整的参数介绍和官方配置示例

11、ConsoleAppender  

  将LogEvent输出到命令行。有两个比较有意思的参数,一个是layout,用来指定输出字串的格式(format);另一个是target,用来指定输出的是 "SYSTEM_OUT" 还是 "SYSTEM_ERR",默认情况下是"SYSTEM_ERR"。

完整的参数介绍和官方配置示例

12、FailoverAppender  

维护一个failover appenders队列,系统先尝试一个主appender(primary appender),若不成功,则尝试failover队列中的Appenders,直到有一个成功为止,或都不成功。比较重要的参数有:

primary(String型):用来指定主appender的名称。

failovers(String[]型):一个appender数组,指定的备选的其他appenders。

retryInterval(integer型):用来设定隔多少秒重新尝试主appender,默认为60秒。

完整的参数介绍和官方配置示例

参考资料:

1、Log4j2 Appenders 官网介绍

2、jms topic与jms queue区别

3、Apache Flume

4、The Syslog Protocol

 

 

一个最常用的log4j2的配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="ERROR">
    <Appenders>
        <RollingFile name="RollingFile" fileName="E:/webapp/logs/yadou-manage.log"
                     filePattern="E:/webapp/logs/$${date:yyyy-MM}/yadou-manage-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout>
                <Pattern>%d %-5level [%t]%l - %msg%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="250 MB"/>
            </Policies>
        </RollingFile>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%highlight{%d %-5level [%t]%l - %msg%n}"/>
        </Console>
    </Appenders>
    <Loggers>
        <!--控制输出debug,不继承-->
        <Logger name="com.jia.yadou.manage" level="debug" additivity="false">
            <!--保存文件,只存储info级别以上的日志-->
            <AppenderRef ref="RollingFile" level="info"/>
            <!--控制台打印指定包路径下面的debug-->
            <AppenderRef ref="Console"/>
        </Logger>
        <!--默认info级别-->
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

项目中注意事项:

通常我们的项目有时候是以jar包的形式发布出去,但是此时如果你直接使用lo4j2的api的话,相当于别人依赖你的jar的项目也必须加入log4j2的jar包。这样是高度耦合的。我们不建议这样使用,log4j2官方给出了适配slf4j,我们只需要在项目中加入以下依赖:

<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.6.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.21</version>
</dependency>

然后项目中,我们使用slf4j的api而不要使用lo4j2的api例如:

将LogManager.getLogger(xxx);替换为LoggerFactory.getLogger(xx);

这样当其他项目引入你的jar后,就可以不用强制他们使用log4j2,也不会因为没有log4j2的jar而报错。

异步日志配置:

log4j2最强的是支持异步写日志,这个是我的简单配置:

异步输出,官方有两种方案。第一种是采用配置开关,第二种则是基于异步标签。注意:异步输出日志需要disruptor-3.3.0.jar或者以上的版本来支持。下面我具体的说明下两种情况:

情况一:配置开关

添加一个名字为:log4j2.component.properties文件,放到classpath下面,log4j2会在启动的时候自动加载。然后你的日志输出已经变成了异步输出了。(注意:这种情况,本人在main方法启动函数测试的时候,经常出现不成功,可能需要附加其他配置参数,我也推荐大家使用第二种方式)

Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

情况一:异步标签<AsyncLogger >

你只需要将你要异步输出的块改为AsyncLogger标签就行了。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="ERROR">
    <Properties>
        <!--定义变量-->
        <Property name="filename">E:/webapp/logs/hnmcc_sso/sso.log</Property>
        <Property name="filenameError">E:/webapp/logs/hnmcc_sso/ssoError.log</Property>
    </Properties>

    <Appenders>
        <!--控制台输出-->
        <Console name="STDOUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %l - %msg%n"/>
        </Console>
        <!--入文件-->
        <RollingFile name="RollingFile" fileName="${filename}"
                     filePattern="/webapp/logs/hnmcc_sso/${date:yyyy-MM}/sso-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="%d %-5level [%t]%l - %msg%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="200 MB"/>
                <TimeBasedTriggeringPolicy/>
            </Policies>
            <!--自动删除超过120天的日志压缩文件-->
            <DefaultRolloverStrategy>
                <Delete basePath="${baseDir}" maxDepth="2">
                    <IfFileName glob="*/sso-*.log.gz"/>
                    <IfLastModified age="120d"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
        <!--错误日志入文件-->
        <RollingFile name="RollingFileError" fileName="${filenameError}"
                     filePattern="/webapp/logs/hnmcc_sso/${date:yyyy-MM}/ssoError-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="%d %-5level [%t]%l - %msg%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="200 MB"/>
                <TimeBasedTriggeringPolicy/>
            </Policies>
            <!--自动删除超过120天的日志压缩文件-->
            <DefaultRolloverStrategy>
                <Delete basePath="${baseDir}" maxDepth="2">
                    <IfFileName glob="*/sso-*.log.gz"/>
                    <IfLastModified age="120d"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

    </Appenders>
    <Loggers>
        <!--采用异步输出日志-->
        <AsyncLogger name="com.xwtec.util.Transport" level="info">
            <!--写入info级别-->
            <AppenderRef ref="RollingFile"/>
            <!--写入error级别-->
            <AppenderRef ref="RollingFileError" level="error"/>
        </AsyncLogger>
        <Root level="debug">
            <AppenderRef ref="STDOUT"/>
        </Root>
    </Loggers>
</Configuration>

 

© 著作权归作者所有

共有 人打赏支持
吕兵阳
粉丝 81
博文 274
码字总数 104949
作品 0
郑州
后端工程师
加载中

评论(6)

吕兵阳
吕兵阳

引用来自“最后111”的评论

log4j2 配置目录可以使用通配符吗?
eg:
com.test.**.dao
com.test.**.service

目前没有看到这个资料。
最后111
最后111
log4j2 配置目录可以使用通配符吗?
eg:
com.test.**.dao
com.test.**.service
吕兵阳
吕兵阳

引用来自“风中静草”的评论

Log4j2的日志能写到数据库里吗?比如MySQL,官方没看到有相关配置。

不建议用,他自带的适配器去写数据库,除非你研究过,他底层的机制,例如,失败回滚?以及其他细节的控制?单次插入的量?多久插入一次之类的。
宝塔镇河妖
宝塔镇河妖

引用来自“吕兵阳”的评论

引用来自“风中静草”的评论

Log4j2的日志能写到数据库里吗?比如MySQL,官方没看到有相关配置。

即使有也不建议这样写,写数据库是个耗时操作,即使异步也不太合适。你数据量很大的话,日志可以入kafka,然后再有kafka入db
log4j2mongodb 还不错
吕兵阳
吕兵阳

引用来自“风中静草”的评论

Log4j2的日志能写到数据库里吗?比如MySQL,官方没看到有相关配置。

即使有也不建议这样写,写数据库是个耗时操作,即使异步也不太合适。你数据量很大的话,日志可以入kafka,然后再有kafka入db
千面书生鬼见愁
Log4j2的日志能写到数据库里吗?比如MySQL,官方没看到有相关配置。
纷乱日志框架,你选谁?

why has these blogs 最近在弄项目重构的事情,其中各种项目之间因为时间以及技术选型的问题的日志使用的框架以及版本不一样,各个打印的信息日志也不规范,之前是使用过最多的是log4j系列的...

thomas1111
2016/10/24
29
0
log4j2之环境搭建及基础配置

注 本文是使用 Maven + springMVC + slf4j + log4j2(v2.7) 示例,并不是纯粹的 log4j2 ,如果执行不使用 slf4j,只需要在调用的地方,修改 loggerFactory 即可。 一般情况下,不做特殊配置...

倚楼听风雨_
2016/10/15
876
0
看Filters如何玩转日志

前言 前面一篇博客(《繁华浮尘,倾听Appenders的故事?》)讲到的各种Appender的配置以及使用,当然还有些未写全,更多的可以去查阅官网的资料。本篇博客讲介绍各种的Filter的配置以及相应使用...

thomas1111
2016/10/28
23
0
如何在MyBatis-3.2.7中使用Log4j2 rc2——MyBatis学习笔记之十九

前天我上传了我的MyBatis系列课程(http://edu.51cto.com/course/course_id-1110.html)的第六讲,主要内容是如何使用Log4j2(具体版本为v2.0-rc1)为MyBatis 3.2.7配置日志。实际上目前最新...

NashMaster2011
2014/07/09
0
0
JMX学习以及在log4j中的应用

前言 JMX即Java Managemen Extensions,是一个为应用程序植入管理功能的框架。一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服务实现管理。 常常在编程的过程中...

buglife
2015/01/06
0
15
Java日志系统研究

基本功能 1. 支持多个等级的日志打印:trace,debug,warning,error等等1. 支持按照不同的包名指定不同的等级1. 支持设置全局的默认日志等级1. 打印日志到单个或者多个文件,文件可以按指定...

landyking
2016/07/18
104
0
使用Docker(Mac)搭建 Nginx/Openresty - Kafka - kafkaManager

本文默认读者已经对Docker有一定了解,且清楚使用Docker进行部署的优势。 1.安装Docker(Mac) 官网:https://docs.docker.com/docker-for-mac/install/ 1.1 下载 Docker for Mac 地址:htt...

高广超
05/26
0
0
LogBack简易教程

1.简介   LogBack是一个日志框架,它与Log4j可以说是同出一源,都出自Ceki Gülcü之手。(log4j的原型是早前由Ceki Gülcü贡献给Apache基金会的) 1.1 LogBack,Slf4j,Log4j之间的关系  ...

0了凡0
2016/07/25
97
0
一个简单的 Log4J 示例程序

昨天用Log4J2写了一个示例程序,详见《一个简单的Log4J2示例程序》: http://my.oschina.net/Tsybius2014/blog/706696 今天我尝试用Log4J写一个示例程序。Jar包下载地址如下: http://www.a...

北风其凉
2016/07/06
84
0
Java日志相关记录 (Jul jcl log4j log4j2 Logback SLF4J)

一、写在前面 在java 中实现记录日志的方式有很多种 1. 最初的方式,就是system.print.out ,err 这样直接在控制台打印消息,缺点太多了,这样与业务逻辑无关的代码会变得更多,不能按日志等及...

独钓渔
2015/12/17
669
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

TensorFlow 线性回归 拟合

用tf 对 一次函数进行拟合 效果 loss 简单实现如下 import tensorflow as tfimport numpy as npimport matplotlib.pyplot as plt# 保存显示数据plotdata = {"batchsize": [], "los...

阿豪boy
9分钟前
0
0
JupyterLab安装地图插件

JupyterLab安装地图插件 (本文所述软件还在发展之中,欢迎加入开源项目,提供建议、测试和开发。) 在Jupyter中进行数据分析时,往往需要将数据叠加到地图上。简单的可以利用matplotlib/ec...

openthings
18分钟前
0
0
Coding and Paper Letter(八)

资源整理 1 Coding: 1.Python项目,由Allen Downey撰写的Think Python第二版的LaTeX源代码和支持代码。 ThinkPython2 2.R语言包h3jsr,h3jsr使用V8的神奇力量通过其javascript绑定提供对Ube...

胖胖雕
26分钟前
0
0
skiplist跳跃表

插入删除log(N) TODO

梦想游戏人
27分钟前
1
0
利用世界杯,读懂 Python 装饰器

Python 装饰器是在面试过程高频被问到的问题,装饰器也是一个非常好用的特性, 熟练掌握装饰器会让你的编程思路更加宽广,程序也更加 pythonic。 今天就结合最近的世界杯带大家理解下装饰器。...

p柯西
41分钟前
0
0
Xshell登录阿里云服务器ECS

Xshell登录阿里云服务器ECS 1. 参考资料: 1). 《阿里云服务器怎么用?阿里云服务器使用教程》 链接:http://www.cr173.com/html/50758_1.html 2). eagle-zhang的CSDN博客《Xshell连接不上阿...

SuShine
50分钟前
1
0
IDEA中的HTTP Client Editor测试API

在前后端分离项目,前后端通过api进行通信。如果用postman免费版进行api测试的话,由于无法保存测试脚本到文件,不方便前端查看。 你可以选择付费版。也可以利用IDEA自带的HTTP Client Edito...

hutaishi
53分钟前
0
0
解决“只能通过Chrome网上应用商店安装该程序”的方法

摘要 : 最近有些用户反映某个Chrome插件在安装的时候,提示“只能通过Chrome网上应用商店安装该程序”,为了解决这一问题,Chrome插件网带来了相关的解决方法。 某些用户在Chrome插件网下载了...

沧海一刀
54分钟前
0
0
通过UNIX域套接字传递文件描述符

  传送文件描述符是高并发网络服务编程的一种常见实现方式。Nebula 高性能通用网络框架即采用了UNIX域套接字传递文件描述符设计和实现。本文详细说明一下传送文件描述符的应用。 1. TCP服务...

Bwar
57分钟前
0
0
python操作Excle

# -*- coding: utf-8 -*-from openpyxl import load_workbook, Workbook#index:第几个sheet页,第一个sheet页的index为0def readExcle(filename,index): # 加载excle文件 wb = l......

淺陌离殇
59分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部