private static PdfReader createPdf( String globalTitle, Date creationDate, ScrambleRequest scrambleRequest) throws DocumentException, IOException { azzert(scrambleRequest.scrambles.length > 0); ByteArrayOutputStream pdfOut = new ByteArrayOutputStream(); Rectangle pageSize = PageSize.LETTER; Document doc = new Document(pageSize, 0, 0, 75, 75); PdfWriter docWriter = PdfWriter.getInstance(doc, pdfOut); docWriter.setBoxSize( "art", new Rectangle(36, 54, pageSize.getWidth() - 36, pageSize.getHeight() - 54)); doc.addCreationDate(); doc.addProducer(); if (globalTitle != null) { doc.addTitle(globalTitle); } doc.open(); // Note that we ignore scrambleRequest.copies here. addScrambles(docWriter, doc, scrambleRequest, globalTitle); doc.close(); // TODO - is there a better way to convert from a PdfWriter to a PdfReader? PdfReader pr = new PdfReader(pdfOut.toByteArray()); if (scrambleRequest.fmc) { // We don't watermark the FMC sheets because they already have // the competition name on them. return pr; } pdfOut = new ByteArrayOutputStream(); doc = new Document(pageSize, 0, 0, 75, 75); docWriter = PdfWriter.getInstance(doc, pdfOut); doc.open(); PdfContentByte cb = docWriter.getDirectContent(); for (int pageN = 1; pageN <= pr.getNumberOfPages(); pageN++) { PdfImportedPage page = docWriter.getImportedPage(pr, pageN); doc.newPage(); cb.addTemplate(page, 0, 0); Rectangle rect = pr.getBoxSize(pageN, "art"); // Header ColumnText.showTextAligned( cb, Element.ALIGN_LEFT, new Phrase(Utils.SDF.format(creationDate)), rect.getLeft(), rect.getTop(), 0); ColumnText.showTextAligned( cb, Element.ALIGN_CENTER, new Phrase(globalTitle), (pageSize.getLeft() + pageSize.getRight()) / 2, pageSize.getTop() - 60, 0); ColumnText.showTextAligned( cb, Element.ALIGN_CENTER, new Phrase(scrambleRequest.title), (pageSize.getLeft() + pageSize.getRight()) / 2, pageSize.getTop() - 45, 0); if (pr.getNumberOfPages() > 1) { ColumnText.showTextAligned( cb, Element.ALIGN_RIGHT, new Phrase(pageN + "/" + pr.getNumberOfPages()), rect.getRight(), rect.getTop(), 0); } // Footer String generatedBy = "Generated by " + Utils.getProjectName() + "-" + Utils.getVersion(); ColumnText.showTextAligned( cb, Element.ALIGN_CENTER, new Phrase(generatedBy), (pageSize.getLeft() + pageSize.getRight()) / 2, pageSize.getBottom() + 40, 0); } doc.close(); // TODO - is there a better way to convert from a PdfWriter to a PdfReader? pr = new PdfReader(pdfOut.toByteArray()); return pr; // The PdfStamper class doesn't seem to be working. // pdfOut = new ByteArrayOutputStream(); // PdfStamper ps = new PdfStamper(pr, pdfOut); // // for(int pageN = 1; pageN <= pr.getNumberOfPages(); pageN++) { // PdfContentByte pb = ps.getUnderContent(pageN); // Rectangle rect = pr.getBoxSize(pageN, "art"); // System.out.println(rect.getLeft()); // System.out.println(rect.getWidth()); // ColumnText.showTextAligned(pb, // Element.ALIGN_LEFT, new Phrase("Hello people!"), 36, 540, 0); //// ColumnText.showTextAligned(pb, //// Element.ALIGN_CENTER, new Phrase("HELLO WORLD"), //// (rect.getLeft() + rect.getRight()) / 2, rect.getTop(), 0); // } // ps.close(); // return ps.getReader(); }
public static ByteArrayOutputStream requestsToZip( ServletContext context, String globalTitle, Date generationDate, ScrambleRequest[] scrambleRequests, String password, String generationUrl) throws IOException, DocumentException, ZipException { ByteArrayOutputStream baosZip = new ByteArrayOutputStream(); ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); if (password != null) { parameters.setEncryptFiles(true); parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD); parameters.setPassword(password); } parameters.setSourceExternalStream(true); ZipOutputStream zipOut = new ZipOutputStream(baosZip); HashMap<String, Boolean> seenTitles = new HashMap<String, Boolean>(); for (ScrambleRequest scrambleRequest : scrambleRequests) { String safeTitle = toFileSafeString(scrambleRequest.title); int salt = 0; String tempNewSafeTitle = safeTitle; while (seenTitles.get(tempNewSafeTitle) != null) { tempNewSafeTitle = safeTitle + " (" + (++salt) + ")"; } safeTitle = tempNewSafeTitle; seenTitles.put(safeTitle, true); String pdfFileName = "pdf/" + safeTitle + ".pdf"; parameters.setFileNameInZip(pdfFileName); zipOut.putNextEntry(null, parameters); PdfReader pdfReader = createPdf(globalTitle, generationDate, scrambleRequest); byte[] b = new byte[(int) pdfReader.getFileLength()]; pdfReader.getSafeFile().readFully(b); zipOut.write(b); zipOut.closeEntry(); String txtFileName = "txt/" + safeTitle + ".txt"; parameters.setFileNameInZip(txtFileName); zipOut.putNextEntry(null, parameters); zipOut.write(join(stripNewlines(scrambleRequest.getAllScrambles()), "\r\n").getBytes()); zipOut.closeEntry(); } String safeGlobalTitle = toFileSafeString(globalTitle); String jsonFileName = safeGlobalTitle + ".json"; parameters.setFileNameInZip(jsonFileName); zipOut.putNextEntry(null, parameters); HashMap<String, Object> jsonObj = new HashMap<String, Object>(); jsonObj.put("sheets", scrambleRequests); jsonObj.put("competitionName", globalTitle); jsonObj.put("version", Utils.getProjectName() + "-" + Utils.getVersion()); jsonObj.put("generationDate", generationDate); jsonObj.put("generationUrl", generationUrl); String json = GSON.toJson(jsonObj); zipOut.write(json.getBytes()); zipOut.closeEntry(); String jsonpFileName = safeGlobalTitle + ".jsonp"; parameters.setFileNameInZip(jsonpFileName); zipOut.putNextEntry(null, parameters); String jsonp = "var SCRAMBLES_JSON = " + json + ";"; zipOut.write(jsonp.getBytes()); zipOut.closeEntry(); parameters.setFileNameInZip(safeGlobalTitle + ".html"); zipOut.putNextEntry(null, parameters); InputStream is = context.getResourceAsStream(HTML_SCRAMBLE_VIEWER); BufferedReader in = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line; while ((line = in.readLine()) != null) { line = line.replaceAll("%SCRAMBLES_JSONP_FILENAME%", jsonpFileName); sb.append(line).append("\n"); } zipOut.write(sb.toString().getBytes()); zipOut.closeEntry(); parameters.setFileNameInZip(safeGlobalTitle + ".pdf"); zipOut.putNextEntry(null, parameters); // Note that we're not passing the password into this function. It seems pretty silly // to put a password protected pdf inside of a password protected zip file. ByteArrayOutputStream baos = requestsToPdf(globalTitle, generationDate, scrambleRequests, null); zipOut.write(baos.toByteArray()); zipOut.closeEntry(); zipOut.finish(); zipOut.close(); return baosZip; }