下载xlsx中的URL到指定目录

2023-11-17

  爱情是灯,友情是影子,当灯灭了,你会发现你的周围都是影子。朋友,是在最后可以给你力量的人

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class XLSXDownloader {

    public static void main(String[] args) {
        String xlsxFilePath = "C:\\Users\\Administrator\\Desktop\\123.xlsx"; // 指定XLSX文件路径
        String downloadDirectory = "F:\\123\\"; // 指定下载目录
        int maxThreads = 5; // 最大线程数

        long startTime = System.currentTimeMillis(); // 记录开始时间

        List<Integer> failedRows = new ArrayList<>(); // 用于存储下载失败的行号
        List<String> failedUrls = new ArrayList<>(); // 用于存储下载失败的URL

        try {
            FileInputStream fileInputStream = new FileInputStream(xlsxFilePath);
            Workbook workbook = new XSSFWorkbook(fileInputStream);
            Sheet sheet = workbook.getSheetAt(0); // 假设数据在第一个工作表中

            int totalRows = sheet.getPhysicalNumberOfRows(); // 总表行数

            ExecutorService executorService = Executors.newFixedThreadPool(maxThreads);

            for (int currentRow = 0; currentRow < totalRows; currentRow++) {
                Row row = sheet.getRow(currentRow);

                for (Cell cell : row) {
                    if (cell.getCellType() == CellType.STRING) {
                        String cellValue = cell.getStringCellValue();

                        // 检查单元格内容是否包含 "http://" 或 "https://"
                        if (cellValue.contains("http://") || cellValue.contains("https://")) {
                            final int finalCurrentRow = currentRow;
                            executorService.submit(() -> {
                                try {
                                    downloadFile(cellValue, downloadDirectory, finalCurrentRow, failedUrls);
                                } catch (IOException e) {
                                    System.err.println("下载失败:" + cellValue);
                                    failedRows.add(finalCurrentRow); // 记录下载失败的行号
                                    failedUrls.add(cellValue); // 记录下载失败的URL
                                }
                            });
                        }
                    }
                }
            }

            executorService.shutdown();

            while (!executorService.isTerminated()) {
                // 等待所有线程完成
            }

            if (!failedRows.isEmpty()) {
                generateErrorTable(failedRows, failedUrls, downloadDirectory);
            }

            long endTime = System.currentTimeMillis(); // 记录结束时间
            long totalTime = endTime - startTime; // 计算总耗时时间(毫秒)
            long totalTimeInMinutes = totalTime / (60 * 1000); // 转换成分钟

            System.out.println("下载完成。总耗时时间:" + totalTimeInMinutes + " 分钟");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void downloadFile(String urlString, String downloadDirectory, int currentRow, List<String> failedUrls) throws IOException {
        URL url = new URL(urlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");

        int responseCode = connection.getResponseCode();

        if (responseCode == HttpURLConnection.HTTP_OK) {
            String fileName = urlString.substring(urlString.lastIndexOf('/') + 1);
            String subDirectory = urlString.substring(urlString.indexOf(".com/") + 5, urlString.lastIndexOf('/') + 1);
            String filePath = downloadDirectory + File.separator + subDirectory + fileName;

            File file = new File(filePath);
            file.getParentFile().mkdirs(); // 创建目录层级

            // 输出当前线程下载的是总表的第几行和总表的进度
            System.out.println("线程正在下载总表的第 " + (currentRow + 1) + " 行,总进度 " + (currentRow + 1) + "/" + failedUrls.size());

            try (InputStream inputStream = connection.getInputStream();
                 FileOutputStream outputStream = new FileOutputStream(filePath)) {

                byte[] buffer = new byte[1024];
                int bytesRead;

                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }
        } else {
            throw new IOException("下载失败,HTTP响应码:" + responseCode);
        }
    }

    private static void generateErrorTable(List<Integer> failedRows, List<String> failedUrls, String downloadDirectory) throws IOException {
        String errorTableFilePath = downloadDirectory + File.separator + "error_table.xlsx";
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Errors");

        int rowNum = 0;
        for (int i = 0; i < failedRows.size(); i++) {
            int row = failedRows.get(i);
            String url = failedUrls.get(i);

            Row newRow = sheet.createRow(rowNum++);

            Cell cell1 = newRow.createCell(0);
            cell1.setCellValue("下载失败的行:" + (row + 1));

            Cell cell2 = newRow.createCell(1);
            cell2.setCellValue("下载失败的URL:" + url);
        }

        try (FileOutputStream outputStream = new FileOutputStream(errorTableFilePath)) {
            workbook.write(outputStream);
        }
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

下载xlsx中的URL到指定目录 的相关文章

随机推荐

  • Linux系统使用 NetworkManager 工具来管理网络

    使用 NetworkManager 工具来管理网络 其在命令行下对应的命令是 nmcli 要连接WiFi 相关的命令如下 1 查看网络设备列表 sudo nmcli dev 注意 如果列出的设备状态全部是 unmanaged 的 说明这些网
  • 单纯记录一下主题色样式——笔记

    单纯想 记录一下这个主题样式的设置 HTML代码
  • Prometheus: 通过ConfigMap来添加Grafana仪表盘

    如果你通过kube prometheus stack部署了Prometheus Grafana 那么Grafana中的仪表盘就是通过边车 sidecar 来动态获取的 Sidecar的观察对象是ConfigMap 当ConfigMap中配置
  • JavaFx如何打成exe包并设置exe的图标

    JavaFx如何打成exe包并设置exe的图标 javaFx在本地运行没问题后 想打成exe包 并在没有jdk的环境下使用 可参考以下操作 在pom中添加如下maven插件
  • 利用qt 信号槽传递自定义结构体--借助QVariant

    在前面的博客里 我介绍了利用Q DECLARE METATYPE和qRegsterMetaType来传递自定义的结构体 但是这样做有个缺点 qRegisterMetaType 只能在main 函数里才能发挥作用 https blog csd
  • Towards Open Set Deep Networks:开放世界的目标检测

    文章发表于2016年 文章链接 1 概述 随着深度网络在目标检测领域的发展 网络的性能和准确率都在不断提升 但是存在的一个问题 深度网络很容易被一些图片 在人类看来没有意义 所欺骗 即使我们觉得该图像并不属于某一类别 但是深度网络还是会以高
  • yii2+ueditor百度富文本编辑器+七牛云单图多图均可

    ueditor百度富文本版本 1 4 3 yii2七牛云SDK yii2安装及使用七牛云文件上传 第一步 打开 web ueditor php Uploader class php文件在最顶部引入 yii2安装及使用七牛云文件上传 内com
  • SQL Server 列转行函数 UNPIVOT(大数据)

    SQL Server 列转行函数 UNPIVOT 大数据 在 SQL Server 中 UNPIVOT 是一种用于将列转换为行的函数 它可以帮助我们重新组织和分析数据 本文将详细介绍 UNPIVOT 函数的使用方法以及如何在处理大数据时进行
  • Kafka/Spark消费topic到写出到topic

    1 Kafka的工具类 1 1 从kafka消费数据的方法 消费者代码 def getKafkaDStream ssc StreamingContext topic String groupId String consumerConfigs
  • Git merge并push到远程分支,但又要回滚到merge之前的代码

    1 使用git reflog 查看所有HEAD历史 2 观察日志列表内容 找到这次merge 之前 git log 例 ce7397d8 HEAD 36 commit merge Merge branch develop into rele
  • 编译失败:内部java编译器错误

    idea编译java报错 信息 Eclipse编译器4 6 2用于编译java源 信息 模块sinoWeb由于项目配置 依赖项更改而完全重建 信息 2017 3 23 11 44 编译完成 1个错误 0个警告 5分32秒949ms 错误 j
  • 力扣 - 102、二叉树的层序遍历(剑指Offer - 面试题32:从上到下打印二叉树)

    题目 给你一个二叉树 请你返回其按 层序遍历 得到的节点值 即逐层地 从左到右访问所有节点 示例 二叉树 3 9 20 null null 15 7 3 9 20 15 7 输出层序遍历的结果 3 9 20 15 7 分析 迭代法 用一个队
  • 数据结构——第六章 图

    知识框架 主要掌握深度优先搜索和广度优先搜索 图的基本概念及基本性质 图的存储结构 邻接矩阵 邻接表 邻接多重表和十字链表 及其特性 存储结构之间的转化 基于存储结构上的遍历操作和各种应用 拓扑排序 最小生成树 最短路径和关键路径 等 通常
  • npm 常用操纵

    以下操作均已 mkdirp 模块为例 npm模块库查询 1 远程仓库查询 a 查询仓库中模块的信息 npm info mkdirp 查看大图 b 查询仓库中模块的所有版本 npm view mkdirp versions 查看大图 c 查看
  • Pid算法总结笔记(平衡小车部分)

    Pid的三种形式 直立环 速度环 转向环 这三种环代表了小车的三种不同动作 直立 转向 和运行速度 三种不同的构造 三种不同的控制函数 最终的思想都是通过pid算法来控制 一 Pid算法简介 什么是pid Pid总共有三个字符 分别是p i
  • [Python系列-8]:Python之人工智能 - 基本工具 -2- 随机数生成库

    作者主页 文火冰糖的硅基工坊 https blog csdn net HiWangWenBing 本文网址 https mp csdn net mp blog creation editor 119254076 目录 1 什么需要随机数生成
  • Echarts的tooltip显示自定义格式化解决方案

    前言 今天甲方爸爸提出了要求 需要把图表显示的数据保留百分数的小数点后一位 实际上这个显示的问题之前在后台处理数据的时候就处理过 当时是没有保留小数的 后来要求保留小数点后一位就在后台处理了 谁知道 在前台展示的时候 莫名的出现小数点后十几
  • 大数据分析R中泊松回归模型实例

    如果您知道如何以及何时使用泊松回归 它可能是一个非常有用的工具 在大数据分析R中泊松回归模型实例中 我们将深入研究泊松回归 它是什么以及R程序员如何在现实世界中使用它 具体来说 我们将介绍 1 泊松回归实际上是什么 什么时候应该使用它 2
  • Shell重定向 &>file、2>&1、1>&2 、/dev/null的区别

    在shell脚本中 默认情况下 总是有三个文件处于打开状态 标准输入 键盘输入 标准输出 输出到屏幕 标准错误 也是输出到屏幕 它们分别对应的文件描述符是0 1 2 gt 默认为标准输出重定向 与 1 gt 相同 2 gt 1 意思是把 标
  • 下载xlsx中的URL到指定目录

    爱情是灯 友情是影子 当灯灭了 你会发现你的周围都是影子 朋友 是在最后可以给你力量的人 import org apache poi ss usermodel import org apache poi xssf usermodel XSS