Skip to content

Commit

Permalink
Allow specify page ranges on pdfs (qzind#919)
Browse files Browse the repository at this point in the history
  • Loading branch information
Brett Berenz authored Feb 24, 2022
1 parent e158548 commit eb57b8c
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 7 deletions.
1 change: 1 addition & 0 deletions js/qz-tray.js
Original file line number Diff line number Diff line change
Expand Up @@ -1428,6 +1428,7 @@ var qz = (function() {
* Defaults to paper width.
* @param {number} [data.options.pageHeight] Optional with <code>[html | pdf]</code> formats. Height of the rendering.
* Defaults to paper height for <code>[pdf]</code>, or auto sized for <code>[html]</code>.
* @param {string} [data.options.pageRanges] Optional with <code>[pdf]</code> formats. Comma-separated list of page ranges to include.
* @param {...*} [arguments] Additionally three more parameters can be specified:<p/>
* <code>{boolean} [resumeOnError=false]</code> Whether the chain should continue printing if it hits an error on one the the prints.<p/>
* <code>{string|Array<string>} [signature]</code> Pre-signed signature(s) of the JSON string for containing <code>call</code>, <code>params</code>, and <code>timestamp</code>.<p/>
Expand Down
7 changes: 6 additions & 1 deletion sample.html
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,10 @@ <h3>Pixel Printing</h3>
</label>
<input type="number" id="pPxlWidth" class="form-control pull-right" />
</div>
<div class="form-group form-inline">
<label for="pPxlRange" class="tip" data-toggle="tooltip" title="Comma-separated ranges">Page Range(s)</label>
<input type="text" id="pPxlRange" class="form-control pull-right" />
</div>
</div>
<div class="col-md-6">
<div class="form-group form-inline">
Expand Down Expand Up @@ -3061,7 +3065,8 @@ <h4 class="panel-title">Options</h4>
if (onlyPixel) {
return {
pageWidth: $("#pPxlWidth").val(),
pageHeight: $("#pPxlHeight").val()
pageHeight: $("#pPxlHeight").val(),
pageRanges: $("#pPxlRange").val()
};
} else {
return {
Expand Down
45 changes: 39 additions & 6 deletions src/qz/printer/action/PrintPDF.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.github.zafarkhaja.semver.Version;
import org.apache.commons.ssl.Base64;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.multipdf.Splitter;
import org.apache.pdfbox.pdmodel.PDDocument;
Expand All @@ -13,8 +15,6 @@
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import qz.common.Constants;
import qz.printer.BookBundle;
import qz.printer.PDFWrapper;
Expand All @@ -35,8 +35,11 @@
import java.awt.print.PrinterJob;
import java.io.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class PrintPDF extends PrintPixel implements PrintProcessor {

Expand Down Expand Up @@ -67,6 +70,7 @@ public void parseData(JSONArray printData, PrintOptions options) throws JSONExce

for(int i = 0; i < printData.length(); i++) {
JSONObject data = printData.getJSONObject(i);
HashSet<Integer> pagesToPrint = new HashSet<>();

if (!data.isNull("options")) {
JSONObject dataOpt = data.getJSONObject("options");
Expand All @@ -77,6 +81,26 @@ public void parseData(JSONArray printData, PrintOptions options) throws JSONExce
if (!dataOpt.isNull("pageHeight") && dataOpt.optDouble("pageHeight") > 0) {
docHeight = dataOpt.optDouble("pageHeight") * convert;
}

if (!dataOpt.isNull("pageRanges")) {
String[] ranges = dataOpt.optString("pageRanges", "").split(",");
for(String range : ranges) {
String[] period = range.split("-");

try {
int start = Integer.parseInt(period[0]);
pagesToPrint.add(start);

if (period.length > 1) {
int end = Integer.parseInt(period[period.length - 1]);
pagesToPrint.addAll(IntStream.rangeClosed(start, end).boxed().collect(Collectors.toSet()));
}
}
catch(NumberFormatException nfe) {
log.warn("Unable to parse page range {}.", range);
}
}
}
}

PrintingUtilities.Flavor flavor = PrintingUtilities.Flavor.valueOf(data.optString("flavor", "FILE").toUpperCase(Locale.ENGLISH));
Expand All @@ -102,8 +126,20 @@ public void parseData(JSONArray printData, PrintOptions options) throws JSONExce
}
}

if (pagesToPrint.isEmpty()) {
pagesToPrint.addAll(IntStream.rangeClosed(1, doc.getNumberOfPages()).boxed().collect(Collectors.toSet()));
}

originals.add(doc);
printables.addAll(splitter.split(doc));

List<PDDocument> splitPages = splitter.split(doc);
originals.addAll(splitPages); //ensures non-ranged page will still get closed

for(int pg = 0; pg < splitPages.size(); pg++) {
if (pagesToPrint.contains(pg + 1)) { //ranges are 1-indexed
printables.add(splitPages.get(pg));
}
}
}
catch(FileNotFoundException e) {
throw new UnsupportedOperationException("PDF file specified could not be found.", e);
Expand Down Expand Up @@ -260,9 +296,6 @@ private void rotatePage(PDDocument doc, PDPage page, double rotation) {

@Override
public void cleanup() {
for(PDDocument doc : printables) {
try { doc.close(); } catch(IOException ignore) {}
}
for(PDDocument doc : originals) {
try { doc.close(); } catch(IOException ignore) {}
}
Expand Down

0 comments on commit eb57b8c

Please sign in to comment.