JavaFX 在多个页面上打印 tableview

Posted

技术标签:

【中文标题】JavaFX 在多个页面上打印 tableview【英文标题】:JavaFX print tableview on multiple pages 【发布时间】:2015-11-02 07:58:19 【问题描述】:

所以,我的问题是我需要打印我的 tableview 的内容,但我有这么多的项目,它只打印其中的前 23 个。 我已经在这里找到了一些解决方案,不幸的是它们并没有太大帮助。

这是我的打印方法:

@FXML
private void printIt() 
    Printer printer = Printer.getDefaultPrinter();
    PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.LANDSCAPE, Printer.MarginType.DEFAULT);
    double scaleX = pageLayout.getPrintableWidth() / logBookTable.getBoundsInParent().getWidth();
    double scaleY = pageLayout.getPrintableHeight() / logBookTable.getBoundsInParent().getHeight();
    logBookTable.getTransforms().add(new Scale(scaleX, scaleY));

    PrinterJob job = PrinterJob.createPrinterJob();
    if (job != null) 
        boolean successPrintDialog = job.showPrintDialog(dialogStage);
        if(successPrintDialog)
            boolean success = job.printPage(pageLayout,logBookTable);
            if (success) 
                job.endJob();
            
        
    

【问题讨论】:

【参考方案1】:

打印机打印机 = Printer.getDefaultPrinter();

            Printer printer = Printer.getDefaultPrinter();PrinterJob  printerJob = PrinterJob.createPrinterJob();
            PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.LANDSCAPE, Printer.MarginType.HARDWARE_MINIMUM);
            printerJob.getJobSettings().setPageLayout(pageLayout);
            Stage stage = (Stage) anchorPane.getScene().getWindow();
            boolean openPrintDialog = printerJob.showPrintDialog(stage);
            if(openPrintDialog)
                tableView.setScaleX(0.8);
                tableView.setScaleY(0.8);
                tableView.setTranslateX(-70);
                tableView.setTranslateY(-50);
                ObservableList<List<SimpleStringProperty>> allPrintItems = tableView.getItems();
                ObservableList <List<SimpleStringProperty>> pageList = FXCollections.observableArrayList();
                boolean printing = false;
                for(int i=0; i<allPrintItems.size(); i++) 
                    List<SimpleStringProperty> oneRow = allPrintItems.get(i);
                    pageList.add(oneRow);
                    if(i!=0 && (i%24==0 || i == (allPrintItems.size()-1)))
                        tableView.setItems(pageList);
                        printing = printerJob.printPage(tableView);
                        pageList.clear();
                    
                
                tableView.setItems(allPrintItems);
                if(printing)printerJob.endJob();
                tableView.setScaleX(1.0);
                tableView.setScaleY(1.0);
                tableView.setTranslateX(0);
                tableView.setTranslateY(0);

【讨论】:

虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。【参考方案2】:

在找到答案之前,我浏览了很多帖子。关键是扩展tableview的高度来显示而不需要在屏幕右侧有滚动条。 (有一些方法可以在不扭曲程序布局的情况下做到这一点。我没有在这个问题中解决这部分问题。关于如何完成这项任务有很好的答案。)一旦你将 tableview 的高度扩展到显示所有它是不需要滚动条的行。然后一次打印一页,从零高度开始到一页的负高度。(在这种情况下:向下接近 11 英寸。边框在其中起作用。)下一页应该在最后一页的位置页面结束并打印到近 11 英寸。 (从大约 -11 英寸到大约 -22 英寸。)这种模式一直持续到遍历 tableview 的整个高度。

    Printer printer = Printer.getDefaultPrinter(); //get the default printer
    javafx.print.PageLayout pageLayout = printer.createPageLayout(Paper.NA_LETTER, PageOrientation.PORTRAIT, Printer.MarginType.DEFAULT); //create a pagelayout.  I used Paper.NA_LETTER for a standard 8.5 x 11 in page.
    PrinterJob job = PrinterJob.createPrinterJob();//create a printer job

    if(job.showPrintDialog(taMain.getScene().getWindow()))// this is very useful it allows you to save the file as a pdf instead using all of your printer's paper. A dialog box pops up, allowing you to change the "name" option from your default printer to Adobe pdf. 
    
        double pagePrintableWidth = pageLayout.getPrintableWidth(); //this should be 8.5 inches for this page layout.
        double pagePrintableHeight = pageLayout.getPrintableHeight();// this should be 11 inches for this page layout.


        tblvMain.prefHeightProperty().bind(Bindings.size(tblvMain.getItems()).multiply(35));// If your cells' rows are variable size you add the .multiply and play with the input value until your output is close to what you want. If your cells' rows are the same height, I think you can use .multiply(1). This changes the height of your tableView to show all rows in the table.
        tblvMain.minHeightProperty().bind(tblvMain.prefHeightProperty());//You can probably play with this to see if it's really needed.  Comment it out to find out.
        tblvMain.maxHeightProperty().bind(tblvMain.prefHeightProperty());//You can probably play with this to see if it' really needed.  Comment it out to find out.

        double scaleX = pagePrintableWidth / tblvMain.getBoundsInParent().getWidth();//scaling down so that the printing width fits within the paper's width bound.
        double scaleY = scaleX; //scaling the height using the same scale as the width. This allows the writing and the images to maintain their scale, or not look skewed.
        double localScale = scaleX; //not really needed since everything is scaled down at the same ratio. scaleX is used thoughout the program to scale the print out.

        double numberOfPages = Math.ceil((tblvMain.getPrefHeight() * localScale) / pagePrintableHeight);//used to figure out the number of pages that will be printed.



        //System.out.println("pref Height: " + tblvMain.getPrefHeight());
        //System.out.println("number of pages: " + numberOfPages);


        tblvMain.getTransforms().add(new Scale(scaleX, (scaleY)));//scales the printing. Allowing the width to say within the papers width, and scales the height to do away with skewed letters and images.
        tblvMain.getTransforms().add(new Translate(0, 0));// starts the first print at the top left corner of the image that needs to be printed

        //Since the height of what needs to be printed is longer than the paper's heights we use gridTransfrom to only select the part to be printed for a given page.
        Translate gridTransform = new Translate();
        tblvMain.getTransforms().add(gridTransform);

        //now we loop though the image that needs to be printed and we only print a subimage of the full image.
        //for example: In the first loop we only pint the printable image from the top down to the height of a standard piece of paper. Then we print starting from were the last printed page ended down to the height of the next page. This happens until all of the pages are printed. 
        // first page prints from 0 height to -11 inches height, Second page prints from -11 inches height to -22 inches height, etc. 
        for(int i = 0; i < numberOfPages; i++)
        
            gridTransform.setY(-i * (pagePrintableHeight / localScale));
            job.printPage(pageLayout, tblvMain);
        

        job.endJob();//finally end the printing job.

【讨论】:

【参考方案3】:

自己找到了解决办法

1) 创建循环

2)创建新表并插入未打印的项目

3) 打印

【讨论】:

你怎么知道哪些项目没有被打印(在第一页) 这实际上取决于打印机本身 我的打印机打印了大约 20 个项目,而我的朋友一台打印了 30 个

以上是关于JavaFX 在多个页面上打印 tableview的主要内容,如果未能解决你的问题,请参考以下文章

检测 TableView JavaFX 行上的双击

JavaFX布尔绑定和TableView绑定多个

无法将值插入 tableview - JavaFx

JavaFX TableView分页 - 无法创建基于fxml的解决方案

如何将网格线保留在空的 TableView Javafx 中

JavaFX,如何冻结TableView中某些列的位置