package gov.nysenate.openleg.client.view.bill; import gov.nysenate.openleg.model.base.Version; import gov.nysenate.openleg.model.bill.Bill; import gov.nysenate.openleg.model.bill.BillAmendment; import gov.nysenate.openleg.service.bill.data.BillAmendNotFoundEx; import gov.nysenate.openleg.util.BillTextUtils; import org.apache.pdfbox.exceptions.COSVisitorException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.edit.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDType1Font; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import java.util.List; /** * PDF representation of a bill. */ public class BillPdfView { private static final Float fontSize = 12f; private static final Float top = 740f; private static final Float billMargin = 10f; private static final Float resolutionMargin = 46f; /** * Writes bill text in pdf format to the given OutputStream * * @param bill Bill - The bill that contains the text to write * @param version Version - Identifies an amendment in the passed in bill that will have its text converted to pdf * @param outputStream OutputStream - The stream which will accept the pdf data * @throws IOException * @throws COSVisitorException */ public static void writeBillPdf(Bill bill, Version version, OutputStream outputStream) throws IOException, COSVisitorException { if (bill == null) { throw new IllegalArgumentException("Supplied bill cannot be null when converting to pdf!"); } if (!bill.hasAmendment(version)) { throw new BillAmendNotFoundEx(bill.getBaseBillId().withVersion(version)); } BillAmendment ba = bill.getAmendment(version); List<List<String>> pages; if (ba.getFullText() == null || ba.getFullText().isEmpty()) { pages = Arrays.asList(Arrays.asList("No full text available for " + bill.getBaseBillId().withVersion(version))); } else if (bill.isResolution()) { pages = BillTextUtils.getResolutionPages(ba.getFullText()); } else { pages = BillTextUtils.getBillPages(ba.getFullText()); } try (PDDocument doc = new PDDocument()) { PDFont font = PDType1Font.COURIER; Float margin = billMargin; if (bill.isResolution()) { margin = resolutionMargin; } for (List<String> page : pages) { PDPage pg = new PDPage(PDPage.PAGE_SIZE_LETTER); PDPageContentStream contentStream = new PDPageContentStream(doc, pg); contentStream.beginText(); contentStream.setFont(font, fontSize); contentStream.moveTextPositionByAmount(margin, top); for (String line : page) { contentStream.drawString(line); contentStream.moveTextPositionByAmount(0, -fontSize); } contentStream.endText(); contentStream.close(); doc.addPage(pg); } doc.save(outputStream); } } }