Пример #1
0
 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;
  }
Пример #4
0
  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();
  }
Пример #5
0
  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();
  }