如何解决运行时异常,同时使用 opencsv 将 csv 转换为 bean 空白 csv 文件

How to solve the runtime exception while converting csv to bean using opencsv for blank csv file

要求: 我有两个 csv 文件 input.csv 和 output.csv 目标是从 input.csv 读取数据行,然后对其进行一些处理,如果处理失败,则将失败的 csv 行写入 output.csv

最初input.csv有一些数据,output.csv是空白。 这是主要的 class 文件:

import com.opencsv.bean.ColumnPositionMappingStrategy;
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.StatefulBeanToCsv;
import com.opencsv.bean.StatefulBeanToCsvBuilder;

import java.io.Reader;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;

public class UploadDocUsingCsv {

    private static final String INPUT_CSV_FILE_PATH = "resources/input.csv";
    private static final String OUTPUT_CSV_FILE_PATH = "resources/output.csv"; // this file only contain data whose upload is failed

    public static void main(String args[]) {
        try (
                Reader reader4Input = Files.newBufferedReader(Paths.get(INPUT_CSV_FILE_PATH));
                Reader reader4Output = Files.newBufferedReader(Paths.get(OUTPUT_CSV_FILE_PATH))
        ) {

            // Read Input File
            CsvToBean csvToBean4Input;
            CsvToBeanBuilder csvToBeanBuilder4Input = new CsvToBeanBuilder(reader4Input);
            csvToBeanBuilder4Input.withType(DocumentDetail.class);
            csvToBeanBuilder4Input.withIgnoreLeadingWhiteSpace(true);
            csvToBeanBuilder4Input.withSkipLines(0);
            csvToBean4Input = csvToBeanBuilder4Input.build();

            // Read Output File
            CsvToBean csvToBean4Output;
            CsvToBeanBuilder csvToBeanBuilder4Output= new CsvToBeanBuilder(reader4Output);
            csvToBeanBuilder4Output.withType(DocumentDetail.class);
            csvToBeanBuilder4Output.withIgnoreLeadingWhiteSpace(true);
            csvToBeanBuilder4Output.withSkipLines(1); // skip header
            csvToBean4Output = csvToBeanBuilder4Output.build();

            // Declare Set to contain DocumentDetail object whose data could not be sent
            HashSet<DocumentDetail> documentDetailsNotSent = new HashSet<DocumentDetail>();

            // Call method to upload the document from input file
            Iterator<DocumentDetail> csvDocumentDetailIterator = csvToBean4Input.iterator();
            DocumentDetail csvHeader = csvDocumentDetailIterator.next(); // skip the header
            // documentDetailsNotSent.add(csvHeader);
            while (csvDocumentDetailIterator.hasNext()) {
                DocumentDetail documentDetail = csvDocumentDetailIterator.next();
                System.out.println(documentDetail);
                documentDetailsNotSent.add(documentDetail);
            }


            // Call method to upload the document from output file
            csvDocumentDetailIterator = csvToBean4Output.iterator(); // java.lang.RuntimeException: Error capturing CSV header!
            while (csvDocumentDetailIterator.hasNext()) {
                DocumentDetail documentDetail = csvDocumentDetailIterator.next();
                System.out.println(documentDetail);
                documentDetailsNotSent.add(documentDetail);
            }

            Writer writer4Output = Files.newBufferedWriter(Paths.get(OUTPUT_CSV_FILE_PATH));
            // write the documentDetail objects that are not uploaded to output file
            ArrayList<DocumentDetail> documentDetailNotSetList = new ArrayList<DocumentDetail>(documentDetailsNotSent);
            documentDetailNotSetList.add(0, csvHeader);
            ColumnPositionMappingStrategy mappingStrategy = new ColumnPositionMappingStrategy();
            mappingStrategy.setType(DocumentDetail.class);
            StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer4Output)
                    .withMappingStrategy(mappingStrategy)
                    .build();
            beanToCsv.write(documentDetailNotSetList);

            writer4Output.close();

        } catch (Exception e){
            System.out.println(e);
        }


    }
}

DocumentDetail class 用作 Bean 在这里:

import com.opencsv.bean.CsvBindByPosition;

import java.util.Objects;

public class DocumentDetail {

    @CsvBindByPosition(position = 0)
    private String contractId;

    @CsvBindByPosition(position = 1)
    private String partyId;

    @CsvBindByPosition(position = 2)
    private String contractBranch;

    @CsvBindByPosition(position = 3)
    private String customerName;

    @CsvBindByPosition(position = 4)
    private String vertical;

    @CsvBindByPosition(position = 5)
    private String referenceContractId;

    @CsvBindByPosition(position = 6)
    private String bankFlowNo;

    @CsvBindByPosition(position = 7)
    private String payoutCategory;

    @CsvBindByPosition(position = 8)
    private String camNo;

    @CsvBindByPosition(position = 9)
    private String camStatus;

    @CsvBindByPosition(position = 10)
    private String folderName;

    @CsvBindByPosition(position = 11)
    private String documentName;

    @CsvBindByPosition(position = 12)
    private String pdfName;

    public String getContractId() {
        return contractId;
    }

    public void setContractId(String contractId) {
        this.contractId = contractId;
    }

    public String getPartyId() {
        return partyId;
    }

    public void setPartyId(String partyId) {
        this.partyId = partyId;
    }

    public String getContractBranch() {
        return contractBranch;
    }

    public void setContractBranch(String contractBranch) {
        this.contractBranch = contractBranch;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getVertical() {
        return vertical;
    }

    public void setVertical(String vertical) {
        this.vertical = vertical;
    }

    public String getReferenceContractId() {
        return referenceContractId;
    }

    public void setReferenceContractId(String referenceContractId) {
        this.referenceContractId = referenceContractId;
    }

    public String getBankFlowNo() {
        return bankFlowNo;
    }

    public void setBankFlowNo(String bankFlowNo) {
        this.bankFlowNo = bankFlowNo;
    }

    public String getPayoutCategory() {
        return payoutCategory;
    }

    public void setPayoutCategory(String payoutCategory) {
        this.payoutCategory = payoutCategory;
    }

    public String getCamNo() {
        return camNo;
    }

    public void setCamNo(String camNo) {
        this.camNo = camNo;
    }

    public String getCamStatus() {
        return camStatus;
    }

    public void setCamStatus(String camStatus) {
        this.camStatus = camStatus;
    }

    public String getFolderName() {
        return folderName;
    }

    public void setFolderName(String folderName) {
        this.folderName = folderName;
    }

    public String getDocumentName() {
        return documentName;
    }

    public void setDocumentName(String documentName) {
        this.documentName = documentName;
    }

    public String getPdfName() {
        return pdfName;
    }

    public void setPdfName(String pdfName) {
        this.pdfName = pdfName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DocumentDetail that = (DocumentDetail) o;
        return contractId.equals(that.contractId) &&
                partyId.equals(that.partyId) &&
                contractBranch.equals(that.contractBranch) &&
                customerName.equals(that.customerName) &&
                vertical.equals(that.vertical) &&
                referenceContractId.equals(that.referenceContractId) &&
                bankFlowNo.equals(that.bankFlowNo) &&
                payoutCategory.equals(that.payoutCategory) &&
                camNo.equals(that.camNo) &&
                camStatus.equals(that.camStatus) &&
                folderName.equals(that.folderName) &&
                documentName.equals(that.documentName) &&
                pdfName.equals(that.pdfName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(contractId, partyId, contractBranch, customerName, vertical, referenceContractId,
                bankFlowNo, payoutCategory, camNo, camStatus, folderName, documentName, pdfName);
    }

    @Override
    public String toString() {
        return "DocumentDetail{" +
                "contractId='" + contractId + '\'' +
                ", partyId='" + partyId + '\'' +
                ", contractBranch='" + contractBranch + '\'' +
                ", customerName='" + customerName + '\'' +
                ", vertical='" + vertical + '\'' +
                ", referenceContractId='" + referenceContractId + '\'' +
                ", bankFlowNo='" + bankFlowNo + '\'' +
                ", payoutCategory='" + payoutCategory + '\'' +
                ", camNo='" + camNo + '\'' +
                ", camStatus='" + camStatus + '\'' +
                ", folderName='" + folderName + '\'' +
                ", documentName='" + documentName + '\'' +
                ", pdfName='" + pdfName + '\'' +
                '}';
    }
}

Input.csv 在这里

CONTRACT _ID,PARTY_ID ,CONTRACT_BRANCH ,CUSTOMER_NAME,VERTICAL ,REFERENCE_CONTRACT_ID ,BANK FLOW NO,PAYOUT CATEGORY,CAM_NO,CAM_STATUS ,FOLDER _NAME ,Document Name,PDF_NAME
133336,362177,xyz,qwe fghfg,fgh,NG233112344,958875934,Purchase Invoice,NA,APPROVED,dfgdfg Construction_dfg,PAYMENT VOUCHER,9588759.pdf

问题是调用csvToBean4Output.iterator();

时如何解决java.lang.RuntimeException: Error capturing CSV header!

我已经通过检查 output.csv 是否为空解决了问题。

代码如下:

boolean empty = (new File(OUTPUT_CSV_FILE_PATH)).length() == 0;
if(!empty){
    csvDocumentDetailIterator = csvToBean4Output.iterator();
    while (csvDocumentDetailIterator.hasNext()) {
        DocumentDetail documentDetail = csvDocumentDetailIterator.next();
        logger.info(documentDetail);
        boolean isSent = commonMethods.uploadDoc(documentDetail);
        logger.info("isSent: " + isSent);
        if(!isSent){
            documentDetailsNotSent.add(documentDetail);
        }
    }
}