Java JTable排序和Jasper报告输出

Java JTable排序和Jasper报告输出,java,swing,jtable,jasper-reports,Java,Swing,Jtable,Jasper Reports,在我的一个基于Java swing桌面的应用程序中,我使用了一个JTable,并为一个列添加了排序功能。我需要根据用户添加的数值对其进行排序,然后获得jasper报告输出 当前,在排序和打印报告后,报告未显示排序顺序。但是从DB中获取值时的顺序。如何打印用户表格排序顺序的报告 这是我的jasper报告生成代码 try { DefaultTableModel de = (DefaultTableModel)Dashboard.catalogTbl.getModel(); JRTab

在我的一个基于Java swing桌面的应用程序中,我使用了一个
JTable
,并为一个列添加了排序功能。我需要根据用户添加的数值对其进行排序,然后获得jasper报告输出

当前,在排序和打印报告后,报告未显示排序顺序。但是从DB中获取值时的顺序。如何打印用户表格排序顺序的报告

这是我的jasper报告生成代码

try {
    DefaultTableModel de = (DefaultTableModel)Dashboard.catalogTbl.getModel();
    JRTableModelDataSource jr = new JRTableModelDataSource(de);
    String reportName = reportPath + "reports/AuctionSale/Catalogue/catalouge_frm_tbl.jrxml";
    String compiledName = reportPath + "reports/AuctionSale/Catalogue/catalouge_frm_tbl.jasper";
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("Lot_No", "Lot No");
    params.put("Mark", "Mark");
    params.put("Invoice", "Invoice");
    params.put("Grade", "Grade");
    params.put("Weight", "Weight");
    params.put("Price", "Price");
    params.put("Buyer", "Buyer");
    JasperCompileManager.compileReportToFile(reportName, compiledName);
    JasperPrint jasperPrint = JasperFillManager.fillReport(compiledName, params, jr);
    JasperViewer.viewReport(jasperPrint, false);
} catch (Exception e) {
    e.printStackTrace();
}
试试看{
DefaultTableModel de=(DefaultTableModel)Dashboard.catalogTbl.getModel();
JRTableModelDataSource jr=新的JRTableModelDataSource(de);
字符串reportName=reportPath+“reports/AuctionSale/catalog/catalouge\u frm\u tbl.jrxml”;
字符串compiledName=reportPath+“reports/AuctionSale/catalog/catalouge\u frm\u tbl.jasper”;
Map params=新的HashMap();
参数put(“标段号”、“标段号”);
参数put(“标记”、“标记”);
参数卖出价(“发票”、“发票”);
参数put(“等级”、“等级”);
参数put(“重量”、“重量”);
参数卖出价(“价格”、“价格”);
参数卖出价(“买方”、“买方”);
jasprocmpilemanager.compileReportToFile(reportName,compiledName);
JasperPrint-JasperPrint=JasperFillManager.fillReport(compiledName,params,jr);
JasperViewer.viewReport(jasperPrint,false);
}捕获(例外e){
e、 printStackTrace();
}

我猜报告是基于
表格模型生成的,而典型的排序只影响
JTable
本身,而不影响模型

您可以做的是修饰传递给报表生成器的表模型,以便它接管
JTable
的排序。类似于

public class TableModelDecorator implements TableModel{
  private TableModel delegate;
  private JTable table;

  @Override
  public Object getValueAt( int rowIndex, int columnIndex ) {
    return delegate.getValueAt( table.convertRowIndexToView( rowIndex ), table.convertColumnIndexToView( columnIndex ) );
  }
}

但是对于所有相关的方法来说。

@Robin的答案基本上是正确的,只是翻译成jasper speak:-)

“decorator”是JRDataSource或(此处)JRRewindableDataSource的自定义实现。使其仅为数据,并基于表的行排序器,类似(注意:只是编译的,不是测试的!)

编辑

只是一个非常快速的可运行代码段(太懒了,无法完成完整的报告,忘记了这些文件是如何工作的;-)-因此,我们在这里创建一个表(使用标准SwingX模型),在其RowSorter上创建一个数据源,并循环第一列的值,没有问题:

    JTable table = new JXTable(new AncientSwingTeam());
    JRDataSource source = new JRTableSorterDataSource(table.getRowSorter());
    table.getRowSorter().toggleSortOrder(0);
    JRField field = createField("First Name");
    String firstNames = "First Name: ";
    while (source.next()) {
        firstNames += "\n  " + source.getFieldValue(field);
    }
    LOG.info(firstNames);
有些晚了,但我希望它能帮助某人: 在这段代码中,我要做的是在jTable1中应用过滤器之后,将获得的行放在辅助模型中

然后,我将辅助模型指定给辅助表。那张桌子就是我要寄给JasperReports的

//** jTable1 is the table in the jFrame where the data is loaded and I apply
//the RowFilter or RowSorter filters

    DefaultTableModel dataModel_tableFiltered = null; //auxiliary model
    JTable tableAuxiliary = null; //table where we will put the auxiliary model

    public constructor {
            
        dataModel_tableFiltered = new DefaultTableModel ();
        // Set the number and name of the columns in the auxiliary model
        for (int i = 0; i <jTable1.getColumnCount(); i ++) {
            dataModel_tableFiltered.addColumn(jTable1.getColumnName (i));
        }
        
        tableAuxiliary = new JTable ();
    }



    private void btn_PrintActionPerformed (java.awt.event.ActionEvent evt) {

        fillModel_filtered ();

        try {
            Map params = new HashMap ();
            params.put ("nameCustomer", "**");

            JRDataSource dataSource = new JRTableModelDataSource (tableAuxiliary.getModel ());
            JasperPrint print = JasperFillManager.fillReport (reportPath, params, dataSource);
            JasperViewer.viewReport (print, false); // true == Exit on Close
        } catch (JRException ex) {
            ex.printStackTrace ();
        }

     }

    // Put resulting rows in the model after applying filters in jTable1
    public void fillModel_filtered () {
        dataModel_tableFiltered.setRowCount (0); // Empty rows of the model

        for (int i = 0; i <jTable1.getRowCount (); i ++) {
            Object row [] = new Object [jTable1.getColumnCount ()];
            for (int j = 0; j <jTable1.getColumnCount (); j ++) {
                row [j] = jTable1.getValueAt (i, j);
            }
            dataModel_tableFiltered.addRow (row);
        }
        tableAuxiliary.setModel(dataModel_tableFiltered); // Very Important
    }        
//**jTable1是jFrame中加载数据并应用的表
//RowFilter或RowSorter过滤器
DefaultTableModel dataModel_tableFiltered=null//辅助模型
JTable tableAuxiliary=null//我们将放置辅助模型的表
公共构造函数{
        
dataModel_tableFiltered=新的DefaultTableModel();
//设置辅助模型中列的编号和名称

对于(int i=0;i您可能希望在将来更仔细地查看标记选择。我打赌这不是您所认为的那样。;)顺便说一句@Mujahid什么是,你的问题到底在哪里,因为JasperReports和Java API是由不同的供应商提供的,@AndrewThompson我在这里添加了生成报告的代码。请你再检查一下。感谢提供更多信息的建议和建议正在接近“评论”领域。稍微偏离主题:我在这里很新。你是什么时候使用评论,什么时候使用实际答案?我在常见问题解答中没有遇到过这样的部分。我不确定你是否有任何参考资料,只是过去的经验。我也不确定它是否应该是答案或评论。根据我的经验,这两种方式似乎都有边界。嗨,罗宾,请再次检查问题。我添加了c正如我所想,我用来生成感谢报告的代码,只需传递表模型,它不知道大量应用于hanks的任何排序。我运行该代码,得到以下异常:
java.lang.NullPointerException at action.JRTableSorterDataSource.getFieldValue(JRTableSorterDataSource.java:43)
谢谢。我不会说Jasper,只会说Java和一点Swing;-)@Mujahid,正如我所说的,没有运行-可能在某个地方错过了一个防止null的方法。正如你所知,这个论坛是关于帮助的,而不是做所有的工作-只需找到它:-)@kleopatra:非常感谢。我会尝试的。谢谢
    JTable table = new JXTable(new AncientSwingTeam());
    JRDataSource source = new JRTableSorterDataSource(table.getRowSorter());
    table.getRowSorter().toggleSortOrder(0);
    JRField field = createField("First Name");
    String firstNames = "First Name: ";
    while (source.next()) {
        firstNames += "\n  " + source.getFieldValue(field);
    }
    LOG.info(firstNames);
//** jTable1 is the table in the jFrame where the data is loaded and I apply
//the RowFilter or RowSorter filters

    DefaultTableModel dataModel_tableFiltered = null; //auxiliary model
    JTable tableAuxiliary = null; //table where we will put the auxiliary model

    public constructor {
            
        dataModel_tableFiltered = new DefaultTableModel ();
        // Set the number and name of the columns in the auxiliary model
        for (int i = 0; i <jTable1.getColumnCount(); i ++) {
            dataModel_tableFiltered.addColumn(jTable1.getColumnName (i));
        }
        
        tableAuxiliary = new JTable ();
    }



    private void btn_PrintActionPerformed (java.awt.event.ActionEvent evt) {

        fillModel_filtered ();

        try {
            Map params = new HashMap ();
            params.put ("nameCustomer", "**");

            JRDataSource dataSource = new JRTableModelDataSource (tableAuxiliary.getModel ());
            JasperPrint print = JasperFillManager.fillReport (reportPath, params, dataSource);
            JasperViewer.viewReport (print, false); // true == Exit on Close
        } catch (JRException ex) {
            ex.printStackTrace ();
        }

     }

    // Put resulting rows in the model after applying filters in jTable1
    public void fillModel_filtered () {
        dataModel_tableFiltered.setRowCount (0); // Empty rows of the model

        for (int i = 0; i <jTable1.getRowCount (); i ++) {
            Object row [] = new Object [jTable1.getColumnCount ()];
            for (int j = 0; j <jTable1.getColumnCount (); j ++) {
                row [j] = jTable1.getValueAt (i, j);
            }
            dataModel_tableFiltered.addRow (row);
        }
        tableAuxiliary.setModel(dataModel_tableFiltered); // Very Important
    }