如何将数据导出到 CSV:JTable 上的动态 SQL 查询和动态列名和数据 (Java/Netbeans)

How To Export Data to CSV: Dynamic SQL Query and Dynamic Column Names and data on JTable (Java/Netbeans)

我正在尝试找出将数据从 JTable 导出为 excel 格式(如 CSV 或 XLSX 等)的最简单方法。 问题是数据是动态的,所以基本上用户可以 运行 动态查询并且 he/she 需要导出该数据。

最简单的方法是从 JTable 中读取所有行并使用 POI 库创建一个 excel 文件。

您可以使用以下方法获取 table 数据,您可以将其存储在列表或其他内容中: table.getModel().getValueAt(rowIndex, columnIndex);

现在要创建 excel 文件,您可以使用 POI 库中的以下代码

WorkbookSettings ws = new WorkbookSettings();
ws.setLocale(new Locale("en", "EN"));
WritableWorkbook workbook = null;
File newFile = new File(dir.getPath() + "\" + fileName);
workbook = Workbook.createWorkbook(newFile, ws);
WritableSheet s = workbook.createSheet("mySheet", 0);
for (int i = 1; i <= <columncount>; ++i) {
Label l = new Label(i - 1, 0, <columnname>, cf);
s.addCell(l);
}

for (int j = 1; j <= <rowcount>; j++) {
    for (int i = 1; i <= <columncount>; i++) {
        Label m = new Label(i - 1, j, <rowvalue>, cf);
        s.addCell(m);
    }
}
workbook.write();
workbook.close();`

这是我用来做这个技巧的 class。它完全按照在视图中呈现给用户的方式导出 JTable(包括行和列的顺序)。如果您使用它们,它还可以直接从 JLabel 自定义渲染器中提取文本。我在没有编译的情况下对 post 做了一些小改动,如果有问题请告诉我...

请注意,这是重复的问题 How to export a JTable to a .csv file?How to export data from JTable to CSV 尽管答案仅包含伪代码。

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JLabel;
import javax.swing.JTable;

public class JTableCSVExporter {


    protected char columnDelimiter = ',';

    public char getColumnDelimiter() {
        return columnDelimiter;
    }

    public void setColumnDelimiter(char columnDelimiter) {
        this.columnDelimiter = columnDelimiter;
    }
    protected char rowDelimiter = '\n';

    public char getRowDelimiter() {
        return rowDelimiter;
    }

    public void setRowDelimiter(char rowDelimiter) {
        this.rowDelimiter = rowDelimiter;
    }

    protected char quote = '"';

    public char getQuote() {
        return quote;
    }

    public void setQuote(char quote) {
        this.quote = quote;
    }


    protected boolean useRenderers = true;

    public boolean isUseRenderers() {
        return useRenderers;
    }

    /**
     * If true, the value provided by table renderers (if they are JLabel) is used as value for CSV.
     * If false, or the renderer is not JLabel, the class uses toString of the cell value.
     */
    public void setUseRenderers(boolean useRenderers) {
        this.useRenderers = useRenderers;
    }

    protected boolean translateBools = true;

    public boolean isTranslateBools() {
        return translateBools;
    }

    /**
     * If true, bools are translated to "yes" a "no". Otherwise toString() is used
     */
    public void setTranslateBools(boolean translateBools) {
        this.translateBools = translateBools;
    }


    /**
     * Exports table to file.
     * @throws IOException 
     */
    public void exportCSV(JTable table, File file) throws IOException {
        FileWriter out = new FileWriter(file);
        for (int i = 0; i < table.getColumnCount(); i++) {
            int columnIndex = table.convertColumnIndexToView(i);
            if (columnIndex != -1) {
                out.write(table.getColumnName(columnIndex) + columnDelimiter);
            }
        }
        out.write(rowDelimiter);

        for (int rowIndex = 0; rowIndex < table.getRowCount(); rowIndex++) {
            for (int j = 0; j < table.getColumnCount(); j++) {
                int columnIndex = table.convertColumnIndexToView(j);
                if (columnIndex != -1) {
                    String toWrite;


                    Object value = table.getValueAt(rowIndex, columnIndex);

                    java.awt.Component rendererComponent = table.getCellRenderer(rowIndex, columnIndex).getTableCellRendererComponent(table, value, false, false, rowIndex, columnIndex);

                    if (isUseRenderers() && rendererComponent instanceof JLabel) {
                        toWrite = ((JLabel) rendererComponent).getText();
                    } else {
                        if (isTranslateBools() &&  value instanceof Boolean) {
                            if (value.equals(Boolean.TRUE)) {
                                toWrite = "yes";
                            } else {
                                toWrite = "no";
                            }
                        } else {
                            if (value == null) {
                                toWrite = "";
                            } else {
                                toWrite = value.toString();
                            }
                        }
                    }
                    out.write(quote + toWrite.replace(Character.toString(quote), "\" + quote) + quote + columnDelimiter);
                }
            }
            out.write(rowDelimiter);
        }

        out.close();
    }
}