You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle ADF 11g:如何将PDF文件发送至打印队列

Batch Printing Selected PDFs in ADF Faces

Great question! Let's break down how to implement batch printing of your selected PDFs without opening each one individually. While a ValueChangeListener can track selections, a batch-triggered action (like a dedicated print button) will be more efficient and user-friendly. Here are two solid approaches:

This approach combines all selected PDFs into a single document server-side, then serves it to the browser with a print trigger. It gives users a single print dialog, which is far smoother than multiple prompts.

Step 1: Update the Page Components

First, adjust your checkbox to bind to a selection map in your backing bean, and pass the PDF download URL as an attribute:

<af:panelGroupLayout id="pgl12" styleClass="itemAction" inlineStyle="padding:10px; vertical-align:bottom;">
  <af:selectBooleanCheckbox id="dc_sbc1" 
                            value="#{viewScope.printingBean.selectedReports[attrs.item.id]}"
                            label="Add">
    <f:attribute name="downloadURL" value="#{attrs.item.downloadURL}"/>
  </af:selectBooleanCheckbox>
  <af:outputText id="print-label" styleClass="directoryButtonLabel" value="Add"/>
</af:panelGroupLayout>

<!-- Add a batch print button somewhere on your page -->
<af:button text="Print Selected PDFs" 
           actionListener="#{viewScope.printingBean.printSelectedReports}"
           onclick="setTimeout(function() { window.print(); }, 1500);"/>

Step 2: Backing Bean Implementation

Use a library like Apache PDFBox to merge the selected PDFs. Here's the bean code:

import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;

public class PrintingBean {
    private Map<String, Boolean> selectedReports = new HashMap<>();

    public void printSelectedReports(ActionEvent event) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
        
        try {
            PDFMergerUtility merger = new PDFMergerUtility();
            ByteArrayOutputStream mergedStream = new ByteArrayOutputStream();

            // Replace this with your actual method to fetch all report items
            List<ReportItem> allReports = getYourFullReportList();
            
            for (ReportItem item : allReports) {
                Boolean isSelected = selectedReports.get(item.getId());
                if (Boolean.TRUE.equals(isSelected)) {
                    // Fetch the PDF from the download URL
                    URL pdfUrl = new URL(item.getDownloadURL());
                    InputStream pdfStream = pdfUrl.openStream();
                    merger.addSource(pdfStream);
                }
            }

            // Merge all selected PDFs into one stream
            merger.setDestinationStream(mergedStream);
            merger.mergeDocuments();

            // Configure response to display the merged PDF inline
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "inline; filename=selected_reports.pdf");
            response.setContentLength(mergedStream.size());
            
            // Write the merged PDF to the response
            mergedStream.writeTo(response.getOutputStream());
            facesContext.responseComplete();
        } catch (Exception e) {
            // Add a FacesMessage to notify users of errors
            e.printStackTrace();
        }
    }

    // Getter/Setter for selectedReports
    public Map<String, Boolean> getSelectedReports() {
        return selectedReports;
    }

    public void setSelectedReports(Map<String, Boolean> selectedReports) {
        this.selectedReports = selectedReports;
    }

    // Replace with your actual method to retrieve all report items
    private List<ReportItem> getYourFullReportList() {
        // Your logic to fetch the list of reports being iterated in the JSF page
        return null;
    }
}

Step 3: Add PDFBox Dependency

If using Maven, include this in your pom.xml:

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.32</version> <!-- Use the latest stable version -->
</dependency>

Option 2: Frontend Print Trigger (No Merging)

If merging PDFs server-side isn't feasible, you can trigger print dialogs for each selected PDF via JavaScript. Note: This will prompt users for each PDF, which is less ideal but works for small batches.

Update the Page

Add a data attribute to your checkbox and a print button with a JS handler:

<af:selectBooleanCheckbox id="dc_sbc1" 
                          styleClass="print-selection"
                          data-pdf-url="#{attrs.item.downloadURL}"
                          value="#{viewScope.printingBean.selectedReports[attrs.item.id]}">
</af:selectBooleanCheckbox>

<af:button text="Print Selected PDFs" onclick="printSelectedPDFs(); return false;"/>

Add JavaScript

function printSelectedPDFs() {
    const checkedBoxes = document.querySelectorAll('.print-selection:checked');
    
    checkedBoxes.forEach(checkbox => {
        const pdfUrl = checkbox.getAttribute('data-pdf-url');
        // Create a hidden iframe to load the PDF
        const iframe = document.createElement('iframe');
        iframe.style.display = 'none';
        iframe.src = pdfUrl;
        
        iframe.onload = () => {
            // Trigger print after the PDF loads
            setTimeout(() => {
                iframe.contentWindow.print();
                // Clean up the iframe after printing
                setTimeout(() => document.body.removeChild(iframe), 500);
            }, 1000);
        };
        
        document.body.appendChild(iframe);
    });
}

Using ValueChangeListener (If You Prefer)

If you want to track selections as users check boxes, update your checkbox and bean like this:

<af:selectBooleanCheckbox id="dc_sbc1" 
                          autoSubmit="true"
                          valueChangeListener="#{viewScope.printingBean.printerCheckboxListener}">
    <f:attribute name="downloadURL" value="#{attrs.item.downloadURL}"/>
</af:selectBooleanCheckbox>

Bean code:

import javax.faces.event.ValueChangeEvent;
import java.util.ArrayList;
import java.util.List;

public class PrintingBean {
    private List<String> printQueue = new ArrayList<>();

    public void printerCheckboxListener(ValueChangeEvent event) {
        Boolean isChecked = (Boolean) event.getNewValue();
        String pdfUrl = (String) event.getComponent().getAttributes().get("downloadURL");
        
        if (isChecked) {
            if (!printQueue.contains(pdfUrl)) {
                printQueue.add(pdfUrl);
            }
        } else {
            printQueue.remove(pdfUrl);
        }
    }

    // Add a print button action to process the printQueue (similar to Option 1/2 logic)
}

内容的提问来源于stack exchange,提问作者dsalvado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 21:12:36