使用 Apache POI 根据 csv 工作表更新 Excel 工作表值

2024-03-20

我对java还是个新手。我在 java 语法方面遇到了一些问题。 我的程序应该执行以下过程:

1)它以csv文件作为输入。

2)它以excel文件作为输入。

3) 它应该迭代写入日期的两个文件的第一列。

4) 通过添加 csv 工作表中的信息来更新 excel 文件并保存其更改。

我有一个

我有两个输入示例以及结果 Excel 工作表的外观。

两个输入文件:

导出-csv-输入.csv

导出-excel-输入.xlsx

更新后的 Excel 文件应如下所示:

导出-excel-输出.xlsx

我的 Java 代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class CsvToExcelConverter {

  public static final String SAMPLE_XLSX_FILE_PATH = 
 "C:/Users/blawand/Desktop/CSV_to_Excel/export-excel-test.xlsx";
  public static final String SAMPLE_CSV_FILE_PATH = 
"C:/Users/blawand/Desktop/CSV_to_Excel/export-csv-test.csv";
  public static List<String> dates_csv = new ArrayList<>();
  public static List<String> dates_excel = new ArrayList<>();

  public static void main(String[] args) throws IOException, 
InvalidFormatException {

    try (Reader reader = 
Files.newBufferedReader(Paths.get(SAMPLE_CSV_FILE_PATH));
        CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT);) 
{

      for (CSVRecord csvRecord : csvParser) {
        // Accessing Values by Column Index
         String name = csvRecord.get(0);
        dates_csv.add(name);
      }
      dates_csv.remove(0);
    }

    FileInputStream fsIP = new FileInputStream(new 
File(SAMPLE_XLSX_FILE_PATH));

    /*
     * ================================================================== 
Iterating over all the
     * rows and columns in a Sheet (Multiple ways)
     * ==================================================================
     */

    // Getting the Sheet at index zero
    XSSFWorkbook workbook = new XSSFWorkbook(fsIP);

    XSSFSheet sheet = workbook.getSheetAt(0);

    // Get the Cell at index 2 from the above row
    // Cell cell1 = sheet.getRow(1).getCell(0);
    // for (int i = 0; i < dates_excel.size(); i++) {
    // XSSFRow rowtest = sheet.createRow((short) i + 1);
    // rowtest.createCell(0).setCellValue(dates_csv.get(i));
    //
    // }

    // cell1.setCellValue(dates_csv.get(0));
    // Create a DataFormatter to format and get each cell's value as 
String
    DataFormatter dataFormatter = new DataFormatter();

    for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) 
{
      Row row = sheet.getRow(rowIndex);
      if (row != null) {
        Cell cell = row.getCell(0); // getColumn(0)
        if (cell != null) {
          // Found column and there is value in the cell.
          // String cellValueMaybeNull = cell.getStringCellValue();
          String cellValueMaybeNull = 
dataFormatter.formatCellValue(cell);

      // String to number set
      dates_excel.add(cellValueMaybeNull);

    }
  }
}

System.out.println(dates_csv);
System.out.println(dates_csv.size());
System.out.println(dates_excel);
System.out.println(dates_excel.size());

while (dates_excel == dates_excel) {

  System.out.println("Yes");
  break;
}
fsIP.close();
FileOutputStream output_file = new FileOutputStream(new 
File(SAMPLE_XLSX_FILE_PATH));
workbook.write(output_file);
output_file.close();

  }
}

我已经阅读了这两个文件,但我在更新 Excel 文件并将项目名称添加到正确的日期时遇到问题。如果相同的日期已在 csv 表中写入两次或多次。

您还想了解哪些信息?

我将感谢每一个帮助或建议!


我有一个例子给你,主要是通过代码注释来解释的。尽管如此,该代码基本上执行以下操作:

在构造函数中获取 xlsx 和 csv 文件的文件路径。

更新时,它首先将csv文件的内容读取到一个Map with a LocalDate作为钥匙和List<String>作为价值观。
然后它会遍历工作簿的行,跳过标题行,并将第一列中的日期与Map<LocalDate, List<String>>。如果映射包含该键,它将开始检查该行中的单元格是否存在当前值,并将它们保留在列表中,以便以后不写入它们。
然后它开始将值写入具有关键日期的行的单元格中。

我希望这有帮助。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class CsvXlsxUpdater {

    private static final DateTimeFormatter DATE_TIME_FORMATTER_CSV = DateTimeFormatter.ofPattern("dd.MM.yyyy");

    private Path csvFilePath;
    private Path xlsxFilePath;
    private XSSFWorkbook workbook;
    private XSSFSheet sheet;
    private Map<LocalDate, List<String>> csvContent = new TreeMap<LocalDate, List<String>>();
    private ZoneId zoneId = ZoneId.systemDefault();

    public CsvXlsxUpdater(String pathToCsvFile, String pathToXlsxFile) {
        csvFilePath = Paths.get(pathToCsvFile);
        xlsxFilePath = Paths.get(pathToXlsxFile);
    }

    /**
     * Reads the content of the csv file into the corresponding class variable,
     * which is a {@link TreeMap} that has a {@link LocalDate} as key and a 
     * {@link List<String>} as values.
     */
    private void readCsvContent() {
        List<String> csvLines;

        try {
            csvLines = Files.readAllLines(csvFilePath);

            for (int i = 1; i < csvLines.size(); i++) {
                String line = csvLines.get(i);
                String[] splitValues = line.split(",");

                if (splitValues.length > 1) {
                    List<String> lineValues = Arrays.asList(splitValues);
                    List<String> projects = getProjectValuesFrom(lineValues);
                    LocalDate localDate = LocalDate.parse(lineValues.get(0), DATE_TIME_FORMATTER_CSV);
                    if (csvContent.containsKey(localDate)) {
                        projects.forEach((String project) -> {
                            List<String> csvProjects = csvContent.get(localDate);
                            if (!csvProjects.contains(project)) {
                                csvProjects.add(project);
                            }
                        });
                    } else {
                        csvContent.put(localDate, projects);
                    }
                } else {
                    LocalDate localDate = LocalDate.parse(splitValues[0], DATE_TIME_FORMATTER_CSV);
                    csvContent.put(localDate, new ArrayList<String>());
                }
            }
        } catch (IOException e) {
            System.err.println("CANNOT FIND OR READ CSV FILE: " + e.getMessage());
            e.printStackTrace();
        } catch (UnsupportedOperationException e) {
            System.err.println("UNSUPPORTED OPERATION: " + e.getMessage());
            e.printStackTrace();
        }

    }

    /**
     * Gets the corresponding {@link LocalDate} from a given (and deprecated)
     * {@link Date}
     * 
     * @param date the deprecated {@link Date} object
     * @return the corresponding {@link LocalDate}
     */
    private LocalDate parseLocalDateFrom(Date date) {
        Instant instantDate = date.toInstant();
        return instantDate.atZone(zoneId).toLocalDate();
    }

    /**
     * Takes a list of read values from the csv file and returns a list containing
     * all the values of the given list <strong>except from the first
     * element</strong>, which is a {@link String} representation of a date and
     * should be treated differently in this context.
     * 
     * @param values the original list of {@link String}s
     * @return another list without the first element of the given list
     */
    private List<String> getProjectValuesFrom(List<String> values) {
        List<String> projectValues = new ArrayList<String>();

        for (int i = 1; i < values.size(); i++) {
            String value = values.get(i);
            if (!value.equals("")) {
                projectValues.add(value);
            }
        }

        return projectValues;
    }

    /**
     * Updates the workbook with the values read from the csv file
     */
    public void updateWorkbook() {
        readCsvContent();
        try {
            FileInputStream fis = new FileInputStream(xlsxFilePath.toAbsolutePath().toString());
            workbook = new XSSFWorkbook(fis);
            sheet = workbook.getSheetAt(0);
            
            // iterate over the rows
            Iterator<Row> rowIterator = sheet.rowIterator();
            
            while (rowIterator.hasNext()) {
                XSSFRow row = (XSSFRow) rowIterator.next();
                
                if (row.getRowNum() == 0) {
                    // skip this or set updated headers
                } else {
                    // check if the csvContent contains the value of cell(0)
                    LocalDate dateKey = parseLocalDateFrom(row.getCell(0).getDateCellValue()); 
                    if (csvContent.containsKey(dateKey)) {
                        // if yes, get list-value of the key
                        List<String> values = csvContent.get(dateKey);
                        
                        // check if there are values
                        if (values != null) {
                            if (values.size() > 0) {
                                // if there are, then go checking the cell values
                                List<String> projectsInXlsx = new ArrayList<String>();
                                Iterator<Cell> cellIterator = row.cellIterator();
                                int lastColumnIndex = 1;
                                
                                // go through all cells with a value except from the first one
                                while (cellIterator.hasNext()) {
                                    Cell cell = cellIterator.next();
                                    
                                    // skip the first column as it contains the date
                                    if (cell.getColumnIndex() != 0) {
                                        lastColumnIndex = cell.getColumnIndex();
                                        System.out.println("Accessing cell in column " + lastColumnIndex);
                                        // if there is a cell with a value
                                        if (cell.getStringCellValue() != null) {
                                            if (!cell.getStringCellValue().equals("")) {
                                                // check if the value in the cell is also in the csv values
                                                if (values.contains(cell.getStringCellValue())) {
                                                    projectsInXlsx.add(cell.getStringCellValue());
                                                    lastColumnIndex++;
                                                }
                                            }
                                        }
                                    }
                                }
                                
                                // now go through the values of the csv file
                                int offset = 0; // cell column offset for more than one entry per date
                                for (String value : values) {
                                    if (!projectsInXlsx.contains(value)) {
                                        // create a cell after the last one with a value
                                        row.createCell(lastColumnIndex + offset).setCellValue(value);
                                        offset++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            
            fis.close();
        
            FileOutputStream fileOutputStream = new FileOutputStream(xlsxFilePath.toAbsolutePath().toString());
            workbook.write(fileOutputStream);
            fileOutputStream.flush();
            fileOutputStream.close();
            workbook.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

In a main方法,您只需调用构造函数,将文件路径传递为Strings,然后调用updateWorkbook()方法,因为它首先在内部读取 csv。

Example:

public class CsvXlsxMain {

    private static final String CSV_FILE_PATH = "S:\\ome\\example\\path\\to\\csv-input.csv";
    private static final String XLSX_FILE_PATH = "S:\\ome\\example\\path\\to\\excel-input.xlsx";
    
    public static void main(String[] args) {
        CsvXlsxUpdater cxu = new CsvXlsxUpdater(CSV_FILE_PATH, XLSX_FILE_PATH);
        cxu.updateWorkbook();
    }
}

请记住,这代码未经过充分测试,以后可能会出现资源交替的问题 如果需要,请使用适合您要求的各种 xlsx 和 csv 输入进行测试。

我没有使用任何库来解析csv文件!

我希望这对你有一点帮助……

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

使用 Apache POI 根据 csv 工作表更新 Excel 工作表值 的相关文章

  • 无法使用maven编译java项目

    我正在尝试在 java 16 0 1 上使用 maven 构建 IntelliJ 项目 但它无法编译我的项目 尽管 IntelliJ 能够成功完成 在此之前 我使用maven编译了一个java 15项目 但我决定将所有内容更新到16 0 1
  • Excel - 在一列中查找重复项,然后将数量求和到另一列中?

    查找一列中的重复项 然后将数量求和到另一列中 https i stack imgur com AADjd png DATA RESULT A 1 A 11 A 1 B 7 A 9 C 5 B 2 D 4 B 2 E 8 B 3 C 5 D
  • 来自数据库的 jfreechart 散点图

    如何使用java中的jfreechart绘制mysql数据库表中数据的散点图 我使用过 Swing 库 任何链接都会有帮助 我搜索了谷歌但找不到理解的解决方案 如果您有代码 请提供给我 实际上我确实做了条形图并使用 jfreechart 绘
  • Android 自定义视图不能以正确的方式处理透明度/alpha

    我正在绘制自定义视图 在此视图中 我使用两个不同的绘画和路径对象在画布上绘画 我基本上是在绘制两个重叠的形状 添加 Alpha 后 视图中重叠的部分比图像的其余部分更暗 这是不希望的 但我不知道如何解决它 这是我的代码片段 用于展示我如何在
  • Java套接字:在连接被拒绝异常时重试的最佳方法?

    现在我正在这样做 while true try SocketAddress sockaddr new InetSocketAddress ivDestIP ivDestPort downloadSock new Socket downloa
  • 在 HTTP 标头中发送 UTF-8 值会导致 Mojibake

    我想使用 servlet 发送阿拉伯语数据HTTPServletResponse给客户 我正在尝试这个 response setCharacterEncoding UTF 8 response setHeader Info arabicWo
  • 如果 Excel 中的表格包含单元格引用,如何对其进行排序?

    我在工作表 1 中有一个 Excel 数据表 它引用了许多其他工作表中的各种不同单元格 当我尝试对工作表进行排序或过滤时 引用会随着单元格的移动而发生变化 但是 我不想手动进入每个单元格并在各处插入 符号 因为有些引用是连续的 我可能想稍后
  • Java 数组的最大维数

    出于好奇 在 Java 中数组可以有多少维 爪哇language不限制维数 但是JavaVM规范将维度数限制为 255 例如 以下代码将无法编译 class Main public static void main String args
  • 无法加载或查找主类,可以在命令行中使用,但不能在 IDE 中使用[重复]

    这个问题在这里已经有答案了 在将其标记为重复之前 请先听我说完 我正在尝试使用 gradle 导入一个 java 项目 功能齐全 适用于所有其他笔记本电脑 没有问题 我的项目 100 正常运行 适用于所有其他笔记本电脑 当我的笔记本电脑被重
  • 如何将 Jfreechart(饼图)添加到 netbeans 的面板中

    我正在使用 netbeans gui 编辑器 并且正在尝试添加一个本身位于内部框架中的 Jfreechart 并且这个内部框架我想将其添加到面板中 正如您在此图中看到的那样 抱歉 我无法直接发布图像 因为我新手 http www flick
  • Cloudfoundry:如何组合两个运行时

    cloundfoundry 有没有办法结合两个运行时环境 我正在将 NodeJS 应用程序部署到 IBM Bluemix 现在 我还希望能够执行独立的 jar 文件 但应用程序失败 APP 0 bin sh 1 java not found
  • 如何使用列表作为pandas数据框中的值?

    我有一个数据框 需要列的子集包含具有多个值的条目 下面是一个带有 运行时 列的数据框 其中包含程序在各种条件下的运行时 df condition a runtimes 1 1 5 2 condition b runtimes 0 5 0 7
  • 尝试使用等于“是”或“否”的字符串变量重新启动 do-while 循环

    计算行程距离的非常简单的程序 一周前刚刚开始 我有这个循环用于解决真或假问题 但我希望它适用于简单的 是 或 否 我为此分配的字符串是答案 public class Main public static void main String a
  • 无法捕获 Spring Batch 的 ItemWriter 中的异常

    我正在编写一个 Spring Batch 流程来将数据集从一个系统迁移到另一个系统 在这种情况下 这就像使用RowMapper实现在传递给查询之前从查询构建对象ItemWriter The ItemWriter称为save我的 DAO 上的
  • 将图像添加到自定义 AlertDialog

    我制作了一个 AlertDialog 让用户可以从我显示的 4 个选项中选择一个 前 3 个让他们在单击号码时直接拨打号码 第 4 个显示不同的视图 现在看起来是这样的 由于第四个选项的目的是不同的任务 我想让它看起来不同 因为用户可能会感
  • 挂钩 Eclipse 构建过程吗?

    我希望在 Eclipse 中按下构建按钮时能够运行一个简单的 Java 程序 目前 当我单击 构建 时 它会运行一些 JRebel 日志记录代码 我有一个程序可以解析 JRebel 日志文件并将统计信息存储在数据库中 是否可以编写一个插件或
  • Excel 2010 在 IF 函数中搜索文本 - 单独的单元格数据

    Program Excel 2010 Require 一种将名字 姓氏 电子邮件提取到各个单元格的方法 Data 我的数据有一个包含原始 脏数据 的表 它是原始的并且一团糟 我用一个简单的方法整理它 IF A7 Order 1 然后其余单元
  • Android - 9 补丁

    我正在尝试使用 9 块图片创建一个新的微调器背景 我尝试了很多方法来获得完美的图像 但都失败了 s Here is my 9 patch 当我用Draw 9 patch模拟时 内容看起来不错 但是带有箭头的部分没有显示 或者当它显示时 这部
  • 在哪里存储 Java 的 .properties 文件?

    The Java教程 http download oracle com javase tutorial essential environment properties htmlon using Properties 讨论如何使用 Prop
  • 实例化 Microsoft.Office.Interop.Excel.Application 对象时出现错误:800700c1

    实例化 Microsoft Office Interop Excel Application 以从 winforms 应用程序生成 Excel 时 出现以下错误 这之前是有效的 但突然间它停止工作了 尽管代码和 Excel 版本没有变化 我

随机推荐

  • 使用 mmap 逐行读取文件

    我有一个程序可以逐行读取大小不同的文件 我想使用 mmap 但如何使用它来逐行读取文件 谢谢您的回答 一旦你有mmap 编辑文件后 您可以使该文件可用于合适的流缓冲区 从现有内存中读取数据 然后使用std getline include
  • 如何抑制 Qt Creator 中的警告

    我想知道是否可以在 Qt Creator 中抑制编译器特定的警告 我的 g 4 5 打印 警告 条件表达式中的枚举和非枚举类型 我想摆脱它 因为它非常烦人 乌班图 11 04 x64 g 4 5 QtCreator 2 01 Qt 4 7
  • 库类(来自 Android sdk)取决于程序类(同样,Android sdk)

    我们正在从 Android Gradle 插件 2 3 3 迁移到 Gradle 插件 3 0 1 我们的应用程序由应用程序模块和库模块组成 多个依赖项是可传递的 使用api关键字 但甚至使用implementation没有帮助 全部更改后
  • 如何对包含空元素的对象数组进行排序?

    在我的程序中有一个数组fClasses创建固定长度 7 个对象 每个对象都是一个类FClass其中包含 3Strings an int 和int 这些值是从 txt 文件中读取的 并根据该值添加到数组的特定索引中 int txt 文件中的条
  • 为回归方程选择适当的滞后以及如何解释 VARselect 结果

    我的问题有两个方面 如何为回归方程选择合适的滞后 我有房价的因变量 以及租金 房屋供应 国家股市指数 抵押贷款利率和房屋空置率的自变量 我读了一些书 发现VARselect data lag max 1 or 2 or 3 etc 可以帮助
  • ASP.NET Core应用程序设置生产SSL证书

    我可以在我的开发盒上运行得很好 但不能在产品中运行 我在我的域服务器上安装了 SSL 证书 如何告诉我的 ASP NET Core 应用程序使用哪个证书 我想我需要添加一些东西让它知道 我问是因为目前我得到 无法启动 Kestrel Sys
  • 使用XPATH,如何选择包含特定字符串的任何节点

    假设我有一个如下所示的 XML 文件
  • 如果其他参数为 null,SQL 正确的连接方式

    我有这段代码及其临时表 因此您可以运行它 create table student id int identity 1 1 firstname varchar 50 lastname varchar 50 create table quiz
  • 根据判别器的子集获取判别联合的子集

    打字稿问题 给定一个受歧视的联合类型 interface A discriminator A data string interface B discriminator B data string interface C discrimin
  • 在 R 中使用 download.file 下载时跳过错误文件

    我有大量 pdf 文件的链接 我想在 for 循环中使用 download file 下载这些文件 我的解决方案工作正常 但在遇到错误时停止 许多文件不起作用 我想在 download file 函数中添加一个功能 告诉 R 在下载产生错误
  • 如何强制 Rails ActiveRecord 提交事务刷新

    是否可以强制 ActiveRecord 推送 刷新事务 或只是保存 创建 我有一个时钟工作人员 它在后台为多个任务工作人员创建任务 问题是 时钟工作人员有时会在时钟工作人员信息完全刷新到数据库之前创建一个任务并将其推送给任务工作人员 这会导
  • Linux 中上下文切换需要多长时间?

    我很好奇在 Linux 中更改上下文需要多少个周期 我专门使用 E5405 Xeon x64 但我也很想看看它与其他平台的比较 有一个名为 LMBench 的免费应用程序 由 Larry McVoy 和朋友编写 它提供了一系列操作系统和硬件
  • 初始化词汇表外 (OOV) 标记

    我正在为 NLP 任务构建 TensorFlow 模型 并且使用预训练的 Glove 300d 词向量 嵌入数据集 显然 有些标记无法解析为嵌入 因为它们没有包含在词向量嵌入模型的训练数据集中 例如罕见的名字 我可以用 0 向量替换这些标记
  • 无法验证 的证书,因为它不包含任何 IP SAN

    我正在开发一个 GitLab CI 管道 它将部署我的 docker 堆栈 我正在尝试将 DOCKER HOST 设置为tcp DROPLET IP 2377 但我收到一条错误消息 指出我的证书不包含任何 IP SAN 我正在使用 Digi
  • IDEA插件'github copilot'无法登录github

    我的IDEA插件 GitHub 副驾驶 无法登录 GitHub 正在等待 GitHub 身份验证 但 我的VSCode可以成功登录 另请确保您已成功注册并提供付款方式 https github com features copilot ht
  • UNet随机断开

    对于基本的网络场景 两个玩家变换和偶尔的 RPC 我经常遇到 UNet 丢失的情况 连接因超时而断开 连接会在 5 分钟内可靠地断开 大多数情况下会在 30 秒内断开 我在网上看到 UNet 经常这样做 我尝试过增加NetworkDropT
  • Java HashMap 在 for 循环中的“put”方法

    我在使用时遇到问题HashMap在 for 循环中 我做错了什么吗 我需要做出什么改变吗 下面是代码及其输出 Code public static void main String args ArrayList
  • 自动 Cookie 处理 C#/.NET HttpWebRequest+HttpWebResponse

    有没有办法使用 HttpWebRequest HttpWebResponse 对象自动处理 NET 中的 cookie 我最好只在 NET 环境中寻找 LWP UserAgent 及其行为 perl 的等效项 有什么建议或建议吗 我想你正在
  • 不兼容的库版本:XXX需要2.0.0或更高版本,但Runes提供1.0.0版本

    我试图在 iPhone 上运行 iOS 应用程序 项目编译得很好 但是当应用程序启动时 XCode 控制台显示 dyld Library not loaded rpath Runes framework Runes Referenced f
  • 使用 Apache POI 根据 csv 工作表更新 Excel 工作表值

    我对java还是个新手 我在 java 语法方面遇到了一些问题 我的程序应该执行以下过程 1 它以csv文件作为输入 2 它以excel文件作为输入 3 它应该迭代写入日期的两个文件的第一列 4 通过添加 csv 工作表中的信息来更新 ex