public void addColumn(PdfWriter writer, Rectangle rect, boolean useAscender) throws DocumentException { rect.setBorder(Rectangle.BOX); rect.setBorderWidth(0.5f); rect.setBorderColor(BaseColor.RED); PdfContentByte cb = writer.getDirectContent(); cb.rectangle(rect); Phrase p = new Phrase("This text is added at the top of the column."); ColumnText ct = new ColumnText(cb); ct.setSimpleColumn(rect); ct.setUseAscender(useAscender); ct.addText(p); ct.go(); }
@Override public void postProcess(ITextContext context, File fileIn, File fileOut) { FileInputStream in = null; FileOutputStream out = null; try { in = new FileInputStream(fileIn); out = new FileOutputStream(fileOut); PageNumber pageNumber = context.pageNumber(); int startPage = pageNumber.lookupFrontMatterLastPage(); ColumnText ct = generateTableOfContent(context); pageNumber.continueFrontMatter(); PdfReader reader = new PdfReader(in); Rectangle pageSize = reader.getPageSize(1); PdfStamper stamper = new PdfStamper(reader, out); while (true) { stamper.insertPage(++startPage, pageSize); PdfContentByte under = stamper.getUnderContent(startPage); pageNumber.notifyPageChange(); headerFooter.drawFooter(under, pageNumber.pageInfos()); PdfContentByte canvas = stamper.getOverContent(startPage); ct.setCanvas(canvas); ct.setSimpleColumn(36, 36, 559, 770); if (!ColumnText.hasMoreText(ct.go())) break; } stamper.close(); } catch (FileNotFoundException e) { log.error("Unable to reopen temporary generated file ({})", fileIn, e); } catch (DocumentException e) { log.error("Error during report post-processing from: {}, to: {}", fileIn, fileOut, e); } catch (IOException e) { log.error("Error during report post-processing from: {}, to: {}", fileIn, fileOut, e); } finally { IOUtils.closeQuietly(out); IOUtils.closeQuietly(in); } }
private List<ColumnText> fillTable(float height) { // copy text for simulation List<ColumnText> tt = null; if (breakHandlingParent == null && colIdx >= layoutTable.getNumberOfColumns()) { // more column breaks than available column // we try not to lose content // but results may be different than in open office // anyway it is logical error made by document creator tt = new ArrayList<ColumnText>(); ColumnText t = createColumnText(); tt.add(t); for (int i = 0; i < texts.size(); i++) { PdfPTable table = new PdfPTable(1); table.setWidthPercentage(100.0f); PdfPCell cell = new PdfPCell(); cell.setBorder(Rectangle.NO_BORDER); cell.setPadding(0.0f); cell.setColumn(ColumnText.duplicate(texts.get(i))); table.addCell(cell); t.addElement(table); } } else { tt = new ArrayList<ColumnText>(texts); for (int i = 0; i < tt.size(); i++) { tt.set(i, ColumnText.duplicate(tt.get(i))); } } // clear layout table clearTable(layoutTable, true); setWidthIfNecessary(); // try to fill cells with text ColumnText t = tt.get(0); for (PdfPCell cell : layoutTable.getRow(0).getCells()) { cell.setFixedHeight(height >= 0.0f ? height : -1.0f); cell.setColumn(ColumnText.duplicate(t)); // t.setSimpleColumn( cell.getLeft() + cell.getPaddingLeft(), height >= 0.0f ? -height : PdfPRow.BOTTOM_LIMIT, cell.getRight() - cell.getPaddingRight(), 0); int res = 0; try { res = t.go(true); } catch (DocumentException e) { throw new XWPFConverterException(e); } if (!ColumnText.hasMoreText(res)) { // no overflow in current column if (tt.size() == 1) { // no more text return null; } else { // some text waiting for new column tt.remove(0); t = tt.get(0); } } } return tt; }
public static void createPdf2( List<Participant> participants, boolean exportName, boolean exportGroup, boolean exportRenseignement, OutputStream out) throws IOException, DocumentException { Document document = new Document(PageSize.A4.rotate()); // document.setMargins(0,0,0,0); PdfWriter writer = PdfWriter.getInstance(document, out); document.open(); PdfContentByte cb = writer.getDirectContent(); float documentTop = document.top(); float documentBottom = document.bottom(); float documentHeight = documentTop - documentBottom; float left = document.left(); float right = document.right(); float width = right - left; cb.rectangle(left, documentBottom, width, documentHeight); cb.stroke(); float nameHeightPercent = 0.35f; float groupHeightPercent = 0.25f; float nameTop = documentTop; float nameBottom = nameTop; if (exportName) { nameBottom = nameTop - (documentHeight * nameHeightPercent); } float groupeTop = nameBottom; float groupeBottom = nameBottom; if (exportGroup) { groupeBottom = groupeTop - (documentHeight * groupHeightPercent); } float barcodeTop = groupeBottom; float barcodeBottom = documentBottom; ColumnText columnText; for (Participant participant : participants) { float nameFontSize = 65f; float groupFontSize = 45f; float renseignementFontSize = 35f; if (exportName) { columnText = new ColumnText(cb); columnText.setSimpleColumn(left, nameTop, right, nameBottom); // cb.rectangle(left, nameBottom, width, (nameTop - nameBottom)); // cb.stroke(); columnText.setExtraParagraphSpace(0f); columnText.setAdjustFirstLine(false); columnText.setIndent(0); String txt = participant.getNom().toUpperCase() + " " + participant.getPrenom(); float previousPos = columnText.getYLine(); columnText.setText(null); columnText.addElement(createCleanParagraph(txt, nameFontSize, true)); while (ColumnText.hasMoreText(columnText.go(true))) { nameFontSize = nameFontSize - 0.5f; columnText.setText(null); columnText.addElement(createCleanParagraph(txt, nameFontSize, true)); columnText.setYLine(previousPos); } columnText.setText(null); columnText.addElement(createCleanParagraph(txt, nameFontSize, true)); columnText.setYLine(previousPos); columnText.go(false); } if (exportGroup) { columnText = new ColumnText(cb); columnText.setSimpleColumn(document.left(), groupeTop, document.right(), groupeBottom); float groupeHeight = groupeTop - groupeBottom; // cb.rectangle(document.left(), groupeTop - groupeHeight, document.right() - // document.left(), groupeHeight); // cb.stroke(); columnText.setExtraParagraphSpace(0f); columnText.setAdjustFirstLine(false); columnText.setIndent(0); columnText.setFollowingIndent(0); String txt1 = participant.getGroupe(); String txt2 = exportRenseignement ? participant.getRenseignements() : null; float previousPos = columnText.getYLine(); columnText.setText(null); // columnText.addElement(createCleanParagraph(txt1,groupFontSize,true,txt2,renseignementFontSize,false)); columnText.addElement(createCleanParagraph(txt1, groupFontSize, true)); columnText.addElement(createCleanParagraph(txt2, renseignementFontSize, false)); while (ColumnText.hasMoreText(columnText.go(true))) { groupFontSize = groupFontSize - 0.5f; renseignementFontSize = renseignementFontSize - 0.5f; columnText.setText(null); // columnText.addElement(createCleanParagraph(txt1,groupFontSize,true,txt2,renseignementFontSize,false)); columnText.addElement(createCleanParagraph(txt1, groupFontSize, true)); columnText.addElement(createCleanParagraph(txt2, renseignementFontSize, false)); columnText.setYLine(previousPos); } columnText.setText(null); // columnText.addElement(createCleanParagraph(txt1,groupFontSize,true,txt2,renseignementFontSize,false)); columnText.addElement(createCleanParagraph(txt1, groupFontSize, true)); columnText.addElement(createCleanParagraph(txt2, renseignementFontSize, false)); columnText.setYLine(previousPos); columnText.go(false); } { columnText = new ColumnText(cb); barcodeTop = barcodeTop - 12f; columnText.setSimpleColumn(left, barcodeTop, right, barcodeBottom); float barcodeHeight = barcodeTop - barcodeBottom; // cb.rectangle(left, barcodeTop - barcodeHeight, width, barcodeHeight); // cb.stroke(); columnText.setExtraParagraphSpace(0f); columnText.setAdjustFirstLine(false); columnText.setIndent(0); float previousPos = columnText.getYLine(); columnText.setText(null); columnText.addElement( createCleanBarcode(cb, participant.getNumero(), width, barcodeHeight)); columnText.go(false); } document.newPage(); } document.close(); }
private static void addScrambles( PdfWriter docWriter, Document doc, ScrambleRequest scrambleRequest, String globalTitle) throws DocumentException, IOException { if (scrambleRequest.fmc) { Rectangle pageSize = doc.getPageSize(); for (int i = 0; i < scrambleRequest.scrambles.length; i++) { String scramble = scrambleRequest.scrambles[i]; PdfContentByte cb = docWriter.getDirectContent(); float LINE_THICKNESS = 0.5f; BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); int bottom = 30; int left = 35; int right = (int) (pageSize.getWidth() - left); int top = (int) (pageSize.getHeight() - bottom); int height = top - bottom; int width = right - left; int solutionBorderTop = bottom + (int) (height * .5); int scrambleBorderTop = solutionBorderTop + 40; int competitorInfoBottom = top - (int) (height * .15); int gradeBottom = competitorInfoBottom - 50; int competitorInfoLeft = right - (int) (width * .45); int rulesRight = competitorInfoLeft; int padding = 5; // Outer border cb.setLineWidth(2f); cb.moveTo(left, top); cb.lineTo(left, bottom); cb.lineTo(right, bottom); cb.lineTo(right, top); // Solution border cb.moveTo(left, solutionBorderTop); cb.lineTo(right, solutionBorderTop); // Rules bottom border cb.moveTo(left, scrambleBorderTop); cb.lineTo(rulesRight, scrambleBorderTop); // Rules right border cb.lineTo(rulesRight, gradeBottom); // Grade bottom border cb.moveTo(competitorInfoLeft, gradeBottom); cb.lineTo(right, gradeBottom); // Competitor info bottom border cb.moveTo(competitorInfoLeft, competitorInfoBottom); cb.lineTo(right, competitorInfoBottom); // Competitor info left border cb.moveTo(competitorInfoLeft, gradeBottom); cb.lineTo(competitorInfoLeft, top); // Solution lines int availableSolutionWidth = right - left; int availableSolutionHeight = scrambleBorderTop - bottom; int lineWidth = 25; // int linesX = (availableSolutionWidth/lineWidth + 1)/2; int linesX = 10; int linesY = (int) Math.ceil(1.0 * WCA_MAX_MOVES_FMC / linesX); cb.setLineWidth(LINE_THICKNESS); cb.stroke(); // int allocatedX = (2*linesX-1)*lineWidth; int excessX = availableSolutionWidth - linesX * lineWidth; int moveCount = 0; solutionLines: for (int y = 0; y < linesY; y++) { for (int x = 0; x < linesX; x++) { if (moveCount >= WCA_MAX_MOVES_FMC) { break solutionLines; } int xPos = left + x * lineWidth + (x + 1) * excessX / (linesX + 1); int yPos = solutionBorderTop - (y + 1) * availableSolutionHeight / (linesY + 1); cb.moveTo(xPos, yPos); cb.lineTo(xPos + lineWidth, yPos); moveCount++; } } float UNDERLINE_THICKNESS = 0.2f; cb.setLineWidth(UNDERLINE_THICKNESS); cb.stroke(); cb.beginText(); int availableScrambleSpace = right - left - 2 * padding; int scrambleFontSize = 20; String scrambleStr = "Scramble: " + scramble; float scrambleWidth; do { scrambleFontSize--; scrambleWidth = bf.getWidthPoint(scrambleStr, scrambleFontSize); } while (scrambleWidth > availableScrambleSpace); cb.setFontAndSize(bf, scrambleFontSize); int scrambleY = 3 + solutionBorderTop + (scrambleBorderTop - solutionBorderTop - scrambleFontSize) / 2; cb.showTextAligned(PdfContentByte.ALIGN_LEFT, scrambleStr, left + padding, scrambleY, 0); cb.endText(); int availableScrambleWidth = right - rulesRight; int availableScrambleHeight = gradeBottom - scrambleBorderTop; Dimension dim = scrambleRequest.scrambler.getPreferredSize( availableScrambleWidth - 2, availableScrambleHeight - 2); PdfTemplate tp = cb.createTemplate(dim.width, dim.height); Graphics2D g2 = new PdfGraphics2D(tp, dim.width, dim.height, new DefaultFontMapper()); try { Svg svg = scrambleRequest.scrambler.drawScramble(scramble, scrambleRequest.colorScheme); drawSvgToGraphics2D(svg, g2, dim); } catch (InvalidScrambleException e) { l.log(Level.INFO, "", e); } finally { g2.dispose(); } cb.addImage( Image.getInstance(tp), dim.width, 0, 0, dim.height, rulesRight + (availableScrambleWidth - dim.width) / 2, scrambleBorderTop + (availableScrambleHeight - dim.height) / 2); ColumnText ct = new ColumnText(cb); int fontSize = 15; int marginBottom = 10; int offsetTop = 27; boolean showScrambleCount = scrambleRequest.scrambles.length > 1; if (showScrambleCount) { offsetTop -= fontSize + 2; } cb.beginText(); cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_CENTER, globalTitle, competitorInfoLeft + (right - competitorInfoLeft) / 2, top - offsetTop, 0); offsetTop += fontSize + 2; cb.endText(); cb.beginText(); cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_CENTER, scrambleRequest.title, competitorInfoLeft + (right - competitorInfoLeft) / 2, top - offsetTop, 0); cb.endText(); if (showScrambleCount) { cb.beginText(); offsetTop += fontSize + 2; cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_CENTER, "Scramble " + (i + 1) + " of " + scrambleRequest.scrambles.length, competitorInfoLeft + (right - competitorInfoLeft) / 2, top - offsetTop, 0); cb.endText(); } offsetTop += fontSize + marginBottom; cb.beginText(); fontSize = 15; cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_LEFT, "Competitor: __________________", competitorInfoLeft + padding, top - offsetTop, 0); offsetTop += fontSize + marginBottom; cb.endText(); cb.beginText(); fontSize = 15; cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_LEFT, "WCA ID:", competitorInfoLeft + padding, top - offsetTop, 0); cb.setFontAndSize(bf, 19); int wcaIdLength = 63; cb.showTextAligned( PdfContentByte.ALIGN_LEFT, "_ _ _ _ _ _ _ _ _ _", competitorInfoLeft + padding + wcaIdLength, top - offsetTop, 0); offsetTop += fontSize + (int) (marginBottom * 1.8); cb.endText(); cb.beginText(); fontSize = 11; cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_CENTER, "DO NOT FILL IF YOU ARE THE COMPETITOR", competitorInfoLeft + (right - competitorInfoLeft) / 2, top - offsetTop, 0); offsetTop += fontSize + marginBottom; cb.endText(); cb.beginText(); fontSize = 11; cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_CENTER, "Graded by: _______________ Result: ______", competitorInfoLeft + (right - competitorInfoLeft) / 2, top - offsetTop, 0); offsetTop += fontSize + marginBottom; cb.endText(); cb.beginText(); cb.setFontAndSize(bf, 25f); int MAGIC_NUMBER = 40; // kill me now cb.showTextAligned( PdfContentByte.ALIGN_CENTER, "Fewest Moves", left + (competitorInfoLeft - left) / 2, top - MAGIC_NUMBER, 0); cb.endText(); com.itextpdf.text.List rules = new com.itextpdf.text.List(com.itextpdf.text.List.UNORDERED); rules.add("Notate your solution by writing one move per bar."); rules.add("To delete moves, clearly erase/blacken them."); rules.add("Face moves F, B, R, L, U, and D are clockwise."); rules.add("Rotations x, y, and z follow R, U, and F."); rules.add("' inverts a move; 2 doubles a move. (e.g.: U', U2)"); rules.add("w makes a face move into two layers. (e.g.: Uw)"); rules.add("A [lowercase] move is a cube rotation. (e.g.: [u])"); ct.addElement(rules); int rulesTop = competitorInfoBottom + 55; ct.setSimpleColumn( left + padding, scrambleBorderTop, competitorInfoLeft - padding, rulesTop, 0, Element.ALIGN_LEFT); ct.go(); rules = new com.itextpdf.text.List(com.itextpdf.text.List.UNORDERED); rules.add("You have 1 hour to find a solution."); rules.add("Your solution length will be counted in OBTM."); int maxMoves = WCA_MAX_MOVES_FMC; rules.add("Your solution must be at most " + maxMoves + " moves, including rotations."); rules.add( "Your solution must not be directly derived from any part of the scrambling algorithm."); ct.addElement(rules); MAGIC_NUMBER = 150; // kill me now ct.setSimpleColumn( left + padding, scrambleBorderTop, rulesRight - padding, rulesTop - MAGIC_NUMBER, 0, Element.ALIGN_LEFT); ct.go(); doc.newPage(); } } else { Rectangle pageSize = doc.getPageSize(); float sideMargins = 100 + doc.leftMargin() + doc.rightMargin(); float availableWidth = pageSize.getWidth() - sideMargins; float vertMargins = doc.topMargin() + doc.bottomMargin(); float availableHeight = pageSize.getHeight() - vertMargins; if (scrambleRequest.extraScrambles.length > 0) { availableHeight -= 20; // Yeee magic numbers. This should make space for the headerTable. } int scramblesPerPage = Math.min(MAX_SCRAMBLES_PER_PAGE, scrambleRequest.getAllScrambles().size()); int maxScrambleImageHeight = (int) (availableHeight / scramblesPerPage - 2 * SCRAMBLE_IMAGE_PADDING); int maxScrambleImageWidth = (int) (availableWidth / 2); // We don't let scramble images take up more than half the page if (scrambleRequest.scrambler.getShortName().equals("minx")) { // TODO - If we allow the megaminx image to be too wide, the // megaminx scrambles get really tiny. This tweak allocates // a more optimal amount of space to the scrambles. This is possible // because the scrambles are so uniformly sized. maxScrambleImageWidth = 190; } Dimension scrambleImageSize = scrambleRequest.scrambler.getPreferredSize(maxScrambleImageWidth, maxScrambleImageHeight); // First do a dry run just to see if any scrambles require highlighting. // Then do the real run, and force highlighting on every scramble // if any scramble required it. boolean forceHighlighting = false; for (boolean dryRun : new boolean[] {true, false}) { String scrambleNumberPrefix = ""; TableAndHighlighting tableAndHighlighting = createTable( docWriter, doc, sideMargins, scrambleImageSize, scrambleRequest.scrambles, scrambleRequest.scrambler, scrambleRequest.colorScheme, scrambleNumberPrefix, forceHighlighting); if (dryRun) { if (tableAndHighlighting.highlighting) { forceHighlighting = true; continue; } } else { doc.add(tableAndHighlighting.table); } if (scrambleRequest.extraScrambles.length > 0) { PdfPTable headerTable = new PdfPTable(1); headerTable.setTotalWidth(new float[] {availableWidth}); headerTable.setLockedWidth(true); PdfPCell extraScramblesHeader = new PdfPCell(new Paragraph("Extra scrambles")); extraScramblesHeader.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); extraScramblesHeader.setPaddingBottom(3); headerTable.addCell(extraScramblesHeader); if (!dryRun) { doc.add(headerTable); } scrambleNumberPrefix = "E"; TableAndHighlighting extraTableAndHighlighting = createTable( docWriter, doc, sideMargins, scrambleImageSize, scrambleRequest.extraScrambles, scrambleRequest.scrambler, scrambleRequest.colorScheme, scrambleNumberPrefix, forceHighlighting); if (dryRun) { if (tableAndHighlighting.highlighting) { forceHighlighting = true; continue; } } else { doc.add(extraTableAndHighlighting.table); } } } } doc.newPage(); }