导出pom.xml中的依赖

一、前言

功能:根据一个pom.xml文件,将本地maven仓库中相关的依赖文件导出到一个文件夹下,并保留目录原有的层级结构。

该节废话偏多,没心情看的兄弟们直接看第二、三节。

在内网开发过程中,基于maven构建的项目时常会遇到缺依赖的情况,即使在内网环境中有maven私仓环境也无法避免依赖不全的问题,maven给我们提供了依赖管理的功能,通过Maven的中央仓库或国内的镜像服务,我们可以轻松下载和安装第三方库,而无需手动下载和管理添加第三方jar包。这解决了添加第三方jar包、处理jar包之间的依赖关系以及解决jar包之间的冲突等问题‌,由于内网无法链接互联网,导致我们在需要添加新依赖时就变得无比麻烦,一个依赖可能会存在多个依赖,如此循环往复下去无疑会消耗我们很多时间,如果多来几次或不成功的时候甚至会把我们心态搞崩溃。

二、效果

pom.xml中的依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>3.3.2</version>
    </dependency>

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.6</version>
    </dependency>
</dependencies>

程序执行信息

copy groupId:org.springframework.boot artifactId:spring-boot-starter-web version:3.3.2
copy groupId:org.springframework.boot artifactId:spring-boot-starter version:3.3.2
copy groupId:org.springframework.boot artifactId:spring-boot version:3.3.2
copy groupId:org.springframework.boot artifactId:spring-boot-starter-logging version:3.3.2
copy groupId:ch.qos.logback artifactId:logback-classic version:1.5.6
copy groupId:ch.qos.logback artifactId:logback-core version:1.5.6
copy groupId:org.apache.logging.log4j artifactId:log4j-to-slf4j version:2.23.1
copy groupId:org.apache.logging.log4j artifactId:log4j-api version:2.23.1
copy groupId:org.slf4j artifactId:jul-to-slf4j version:2.0.13
copy groupId:jakarta.annotation artifactId:jakarta.annotation-api version:2.1.1
copy groupId:org.springframework artifactId:spring-core version:6.1.11
copy groupId:org.springframework artifactId:spring-jcl version:6.1.11
copy groupId:org.yaml artifactId:snakeyaml version:2.2
copy groupId:org.springframework.boot artifactId:spring-boot-starter-json version:3.3.2
copy groupId:com.fasterxml.jackson.core artifactId:jackson-databind version:2.17.2
copy groupId:com.fasterxml.jackson.core artifactId:jackson-annotations version:2.17.2
copy groupId:com.fasterxml.jackson.core artifactId:jackson-core version:2.17.2
copy groupId:com.fasterxml.jackson.datatype artifactId:jackson-datatype-jdk8 version:2.17.2
copy groupId:com.fasterxml.jackson.datatype artifactId:jackson-datatype-jsr310 version:2.17.2
copy groupId:com.fasterxml.jackson.module artifactId:jackson-module-parameter-names version:2.17.2
copy groupId:org.springframework.boot artifactId:spring-boot-starter-tomcat version:3.3.2
copy groupId:org.apache.tomcat.embed artifactId:tomcat-embed-core version:10.1.26
copy groupId:org.apache.tomcat.embed artifactId:tomcat-embed-el version:10.1.26
copy groupId:org.apache.tomcat.embed artifactId:tomcat-embed-websocket version:10.1.26
copy groupId:org.springframework artifactId:spring-web version:6.1.11
copy groupId:org.springframework artifactId:spring-beans version:6.1.11
copy groupId:io.micrometer artifactId:micrometer-observation version:1.12.8
copy groupId:io.micrometer artifactId:micrometer-commons version:1.12.8
copy groupId:org.springframework artifactId:spring-webmvc version:6.1.11
copy groupId:org.springframework artifactId:spring-aop version:6.1.11
copy groupId:org.springframework artifactId:spring-context version:6.1.11
copy groupId:org.springframework artifactId:spring-expression version:6.1.11
copy groupId:com.baomidou artifactId:mybatis-plus-boot-starter version:3.5.6
copy groupId:com.baomidou artifactId:mybatis-plus version:3.5.6
copy groupId:com.baomidou artifactId:mybatis-plus-core version:3.5.6
copy groupId:com.baomidou artifactId:mybatis-plus-annotation version:3.5.6
copy groupId:com.baomidou artifactId:mybatis-plus-extension version:3.5.6
copy groupId:org.mybatis artifactId:mybatis version:3.5.16
copy groupId:com.github.jsqlparser artifactId:jsqlparser version:4.9
copy groupId:org.mybatis artifactId:mybatis-spring version:2.1.2
copy groupId:com.baomidou artifactId:mybatis-plus-spring-boot-autoconfigure version:3.5.6
copy groupId:org.springframework.boot artifactId:spring-boot-autoconfigure version:2.7.15
copy groupId:org.springframework.boot artifactId:spring-boot-starter-jdbc version:2.7.15
copy groupId:com.zaxxer artifactId:HikariCP version:4.0.3
copy groupId:org.slf4j artifactId:slf4j-api version:2.0.0-alpha1
copy groupId:org.springframework artifactId:spring-jdbc version:5.3.29
copy groupId:org.springframework artifactId:spring-tx version:5.3.29

导出依赖到其它目录的内容及结构,内容太长,这里只贴部分内容示意。

├─ch
│  └─qos
│      └─logback
│          ├─logback-classic
│          │  └─1.5.6
│          │          logback-classic-1.5.6.jar
│          │          logback-classic-1.5.6.jar.sha1
│          │          logback-classic-1.5.6.pom
│          │          logback-classic-1.5.6.pom.sha1
│          │          _remote.repositories
│          │
│          └─logback-core
│              └─1.5.6
│                      logback-core-1.5.6.jar
│                      logback-core-1.5.6.jar.sha1
│                      logback-core-1.5.6.pom
│                      logback-core-1.5.6.pom.sha1
│                      _remote.repositories
│
├─com
│  ├─baomidou
│  │  ├─mybatis-plus
│  │  │  └─3.5.6
│  │  │          mybatis-plus-3.5.6.jar
│  │  │          mybatis-plus-3.5.6.jar.sha1
│  │  │          mybatis-plus-3.5.6.pom
│  │  │          mybatis-plus-3.5.6.pom.sha1
│  │  │          _remote.repositories
│  │  │
│  │  ├─mybatis-plus-annotation
│  │  │  └─3.5.6
│  │  │          mybatis-plus-annotation-3.5.6.jar
│  │  │          mybatis-plus-annotation-3.5.6.jar.sha1
│  │  │          mybatis-plus-annotation-3.5.6.pom
│  │  │          mybatis-plus-annotation-3.5.6.pom.sha1
│  │  │          _remote.repositories
│  │  │
│  │  ├─mybatis-plus-boot-starter
│  │  │  └─3.5.6
│  │  │          mybatis-plus-boot-starter-3.5.6.jar
│  │  │          mybatis-plus-boot-starter-3.5.6.jar.sha1
│  │  │          mybatis-plus-boot-starter-3.5.6.pom
│  │  │          mybatis-plus-boot-starter-3.5.6.pom.sha1
│  │  │          _remote.repositories
│  │  │
│  │  ├─mybatis-plus-core
│  │  │  └─3.5.6
│  │  │          mybatis-plus-core-3.5.6.jar
│  │  │          mybatis-plus-core-3.5.6.jar.sha1
│  │  │          mybatis-plus-core-3.5.6.pom
│  │  │          mybatis-plus-core-3.5.6.pom.sha1
│  │  │          _remote.repositories
│  │  │
│  │  ├─mybatis-plus-extension
│  │  │  └─3.5.6
│  │  │          mybatis-plus-extension-3.5.6.jar
│  │  │          mybatis-plus-extension-3.5.6.jar.sha1
│  │  │          mybatis-plus-extension-3.5.6.pom
│  │  │          mybatis-plus-extension-3.5.6.pom.sha1
│  │  │          _remote.repositories
│  │  │
│  │  └─mybatis-plus-spring-boot-autoconfigure
│  │      └─3.5.6
│  │              mybatis-plus-spring-boot-autoconfigure-3.5.6.jar
│  │              mybatis-plus-spring-boot-autoconfigure-3.5.6.jar.sha1
│  │              mybatis-plus-spring-boot-autoconfigure-3.5.6.pom
│  │              mybatis-plus-spring-boot-autoconfigure-3.5.6.pom.sha1
│  │              _remote.repositories
│  │

三、代码

package org.example;

import org.apache.commons.io.FileUtils;

import java.io.*;
import java.text.MessageFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) throws IOException {
        //读取的pom文件
        String pom = "D:\\projects\\test\\dependency-module\\pom.xml";
        //maven仓库地址
        String rep = "D:\\source\\maven\\repository";
        //文件存储的位置
        String out = "D:\\source\\maven\\rep_target";
        //是否覆写_remote.repositories文件
        boolean overwriteRemoteFile = true;

        Process exec = Runtime.getRuntime().exec("cmd /c mvn dependency:list -f " + pom);

        InputStream is = exec.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);

        //源
        File repFile = new File(rep);

        //目标
        File outFile = new File(out);
        if(!outFile.exists()) {
            outFile.mkdirs();
        }

        Pattern pattern = Pattern.compile(".*?\\s+(.*?):(.*):(jar|pom|war):(.*?):.*");



        String content = null;

        while (null != (content = br.readLine())) {
            //System.out.println(content);
            Matcher matcher = pattern.matcher(content);

            boolean matches = matcher.matches();
            if(matches) {
                Dependency dependency = new Dependency(matcher.group(1), matcher.group(2), matcher.group(4));
                System.out.println("copy " + dependency);

                dependency.copy(repFile,outFile,overwriteRemoteFile);

            }
        }

        br.close();
        isr.close();
        is.close();
        System.out.println("final...");
    }

    static class Dependency {
        public Dependency (String groupId,String artifactId,String version) {
            this.groupId = groupId;
            this.artifactId = artifactId;
            this.version = version;
        }

        private String groupId;
        private String artifactId;
        private String version;

        @Override
        public String toString() {
            return MessageFormat.format("groupId:{0} artifactId:{1} version:{2}",groupId,artifactId,version);
        }

        public void copy(File source,File target,boolean overwrite) throws IOException {
            String path = groupId.replace(".","\\") + "\\" + artifactId + "\\" + version;

            //System.out.println(path);
            File s = new File(source,path);

            if(s.exists()) {
                File t = new File(target,path);
                if(!t.exists()) {
                    t.mkdirs();
                }

                FileUtils.copyDirectory(s,t);

                if(overwrite) {
                    File[] files = t.listFiles(file -> file.getName().equals("_remote.repositories"));

                    if(null != files && files.length != 0) {
                        File file = files[0];
                        FileOutputStream fos = new FileOutputStream(file);
                        OutputStreamWriter osw = new OutputStreamWriter(fos);
                        BufferedWriter bw = new BufferedWriter(osw);

                        bw.write(artifactId + "-" + version + ".pom>central=");
                        bw.newLine();
                        bw.write(artifactId + "-" + version + ".jar>central=");

                        bw.flush();
                        bw.close();
                        osw.close();
                        fos.close();
                    }
                }
            } else {
                System.err.println("file not fond ... ,please manual handle");
            }
        }
    }
}

四、解释

通过mvn dependency命令获取pom.xml中的依赖项,通过正则匹配每个依赖的groupIdartifactIdversion,通过这三个内容可以定位maven仓库中的位置,将文件按照目录复制到目标文件夹下,如果需要覆写_remote.repositories,则重新生成内容写入到_remote.repositories文件中。

cmd /c mvn dependency:list -f D:\projects\test\dependency-module\pom.xml命令可以打印一个pom.xml中的所有依赖内容,效果如下。

[INFO] Scanning for projects...
[INFO]
[INFO] -------------------< org.example:dependency-module >--------------------
[INFO] Building dependency-module 1.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- dependency:3.7.0:list (default-cli) @ dependency-module ---
[INFO]
[INFO] The following files have been resolved:
[INFO]    org.springframework.boot:spring-boot-starter-web:jar:3.3.2:compile -- module spring.boot.starter.web [auto]
[INFO]    org.springframework.boot:spring-boot-starter:jar:3.3.2:compile -- module spring.boot.starter [auto]
[INFO]    org.springframework.boot:spring-boot:jar:3.3.2:compile -- module spring.boot [auto]
[INFO]    org.springframework.boot:spring-boot-starter-logging:jar:3.3.2:compile -- module spring.boot.starter.logging [auto]
[INFO]    ch.qos.logback:logback-classic:jar:1.5.6:compile -- module ch.qos.logback.classic
[INFO]    ch.qos.logback:logback-core:jar:1.5.6:compile -- module ch.qos.logback.core
[INFO]    org.apache.logging.log4j:log4j-to-slf4j:jar:2.23.1:compile -- module org.apache.logging.log4j.to.slf4j
[INFO]    org.apache.logging.log4j:log4j-api:jar:2.23.1:compile -- module org.apache.logging.log4j
[INFO]    org.slf4j:jul-to-slf4j:jar:2.0.13:compile -- module jul.to.slf4j
[INFO]    jakarta.annotation:jakarta.annotation-api:jar:2.1.1:compile -- module jakarta.annotation
[INFO]    org.springframework:spring-core:jar:6.1.11:compile -- module spring.core [auto]
[INFO]    org.springframework:spring-jcl:jar:6.1.11:compile -- module spring.jcl [auto]
[INFO]    org.yaml:snakeyaml:jar:2.2:compile -- module org.yaml.snakeyaml
[INFO]    org.springframework.boot:spring-boot-starter-json:jar:3.3.2:compile -- module spring.boot.starter.json [auto]
[INFO]    com.fasterxml.jackson.core:jackson-databind:jar:2.17.2:compile -- module com.fasterxml.jackson.databind
[INFO]    com.fasterxml.jackson.core:jackson-annotations:jar:2.17.2:compile -- module com.fasterxml.jackson.annotation
[INFO]    com.fasterxml.jackson.core:jackson-core:jar:2.17.2:compile -- module com.fasterxml.jackson.core
[INFO]    com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.17.2:compile -- module com.fasterxml.jackson.datatype.jdk8
[INFO]    com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.17.2:compile -- module com.fasterxml.jackson.datatype.jsr310
[INFO]    com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.17.2:compile -- module com.fasterxml.jackson.module.paramnames
[INFO]    org.springframework.boot:spring-boot-starter-tomcat:jar:3.3.2:compile -- module spring.boot.starter.tomcat [auto]
[INFO]    org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.26:compile -- module tomcat.embed.core (auto)
[INFO]    org.apache.tomcat.embed:tomcat-embed-el:jar:10.1.26:compile -- module tomcat.embed.el (auto)
[INFO]    org.apache.tomcat.embed:tomcat-embed-websocket:jar:10.1.26:compile -- module tomcat.embed.websocket (auto)
[INFO]    org.springframework:spring-web:jar:6.1.11:compile -- module spring.web [auto]
[INFO]    org.springframework:spring-beans:jar:6.1.11:compile -- module spring.beans [auto]
[INFO]    io.micrometer:micrometer-observation:jar:1.12.8:compile -- module micrometer.observation [auto]
[INFO]    io.micrometer:micrometer-commons:jar:1.12.8:compile -- module micrometer.commons [auto]
[INFO]    org.springframework:spring-webmvc:jar:6.1.11:compile -- module spring.webmvc [auto]
[INFO]    org.springframework:spring-aop:jar:6.1.11:compile -- module spring.aop [auto]
[INFO]    org.springframework:spring-context:jar:6.1.11:compile -- module spring.context [auto]
[INFO]    org.springframework:spring-expression:jar:6.1.11:compile -- module spring.expression [auto]
[INFO]    com.baomidou:mybatis-plus-boot-starter:jar:3.5.6:compile -- module com.baomidou.mybatis.plus.boot.starter [auto]
[INFO]    com.baomidou:mybatis-plus:jar:3.5.6:compile -- module com.baomidou.mybatis.plus [auto]
[INFO]    com.baomidou:mybatis-plus-core:jar:3.5.6:compile -- module com.baomidou.mybatis.plus.core [auto]
[INFO]    com.baomidou:mybatis-plus-annotation:jar:3.5.6:compile -- module com.baomidou.mybatis.plus.annotation [auto]
[INFO]    com.baomidou:mybatis-plus-extension:jar:3.5.6:compile -- module com.baomidou.mybatis.plus.extension [auto]
[INFO]    org.mybatis:mybatis:jar:3.5.16:compile -- module org.mybatis [auto]
[INFO]    com.github.jsqlparser:jsqlparser:jar:4.9:compile -- module net.sf.jsqlparser [auto]
[INFO]    org.mybatis:mybatis-spring:jar:2.1.2:compile -- module org.mybatis.spring [auto]
[INFO]    com.baomidou:mybatis-plus-spring-boot-autoconfigure:jar:3.5.6:compile -- module com.baomidou.mybatis.plus.spring.boot.autoconfigure [auto]
[INFO]    org.springframework.boot:spring-boot-autoconfigure:jar:2.7.15:compile -- module spring.boot.autoconfigure [auto]
[INFO]    org.springframework.boot:spring-boot-starter-jdbc:jar:2.7.15:compile -- module spring.boot.starter.jdbc [auto][INFO]    com.zaxxer:HikariCP:jar:4.0.3:compile -- module com.zaxxer.hikari
[INFO]    org.slf4j:slf4j-api:jar:2.0.0-alpha1:compile -- module org.slf4j
[INFO]    org.springframework:spring-jdbc:jar:5.3.29:compile -- module spring.jdbc [auto]
[INFO]    org.springframework:spring-tx:jar:5.3.29:compile -- module spring.tx [auto]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.758 s
[INFO] Finished at: 2024-09-03T16:24:16+08:00
[INFO] ------------------------------------------------------------------------

".*?\\s+(.*?):(.*):(jar|pom|war):(.*?):.*"正则可以匹配到依赖项,并通过正则表达式中的分组提取出groupIdartifactIdversion

_remote.repositories的作用,通常来说覆写是很有必要的。

使用Hutool 5.7.16版本导出Excel并合并同一列相同内容的行,可以按照以下步骤进行: 1. 引入Hutool依赖 在你的Maven项目引入Hutool的依赖: ```xml <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.16</version> </dependency> ``` 2. 创建ExcelWriter对象 在Java代码,创建一个ExcelWriter对象,用于导出Excel文件: ```java ExcelWriter writer = ExcelUtil.getWriter("output.xlsx"); ``` 3. 写入表头和数据 使用ExcelWriter对象的writeRow()方法,写入表头和数据: ```java // 写入表头 writer.writeRow(Arrays.asList("姓名", "年龄", "性别")); // 写入数据 List<List<Object>> rows = Arrays.asList( Arrays.asList("张三", 20, "男"), Arrays.asList("李四", 22, "女"), Arrays.asList("王五", 20, "男"), Arrays.asList("赵六", 22, "女"), Arrays.asList("张三", 23, "男"), Arrays.asList("李四", 25, "女") ); writer.write(rows); ``` 4. 合并同一列相同内容的行 使用Hutool的ExcelUtil.mergeCells()方法,合并同一列相同内容的行: ```java // 合并姓名列 ExcelUtil.mergeCells(writer.getSheet(), 0, 1, 0, 2, null); ``` 其,第一个参数是工作表对象,第二个参数是起始行,第三个参数是结束行,第四个参数是起始列,第五个参数是结束列,最后一个参数是合并后单元格的内容(如果为null,则使用第一个单元格的内容)。 完整的示例代码如下: ```java import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelWriter; import java.util.Arrays; import java.util.List; import java.util.Map; public class ExcelExportDemo { public static void main(String[] args) { // 创建ExcelWriter对象 ExcelWriter writer = ExcelUtil.getWriter("output.xlsx"); // 写入表头 writer.writeRow(Arrays.asList("姓名", "年龄", "性别")); // 写入数据 List<List<Object>> rows = Arrays.asList( Arrays.asList("张三", 20, "男"), Arrays.asList("李四", 22, "女"), Arrays.asList("王五", 20, "男"), Arrays.asList("赵六", 22, "女"), Arrays.asList("张三", 23, "男"), Arrays.asList("李四", 25, "女") ); writer.write(rows); // 合并姓名列 ExcelUtil.mergeCells(writer.getSheet(), 0, 1, 0, 2, null); // 保存Excel文件 writer.flush(); writer.close(); } } ``` 运行该代码,你将得到一个名为“output.xlsx”的Excel文件,其姓名列相同内容的行已经被合并。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值