在 Java 中格式化 pdf

Formatting pdf in Java

我在格式化 pdf 时遇到了一些问题。我已经将文本添加到 pdf 文件,但有问题 - 我不知道 pdf 会是什么样子。我的意思是有不止一个模板,在一个 pdf 文件中我添加了合适的地方,但是在另一个文件中我的文字涵盖了一些重要信息。

/**
* metoda dodaje podpis do pdf
* @param fileDokument
* @throws DocumentException
* @throws IOException
* @throws SQLException 
*/
private void addSignatureToPdf(FileDokument fileDokument) throws DocumentException, IOException, SQLException {
   java.util.Date dateToFind = Calendar.getInstance().getTime();
   DecimalFormat df = new DecimalFormat("00");
   DateTime dt = new DateTime();
   int year = dt.getYear();
   int month = dt.getMonthOfYear();
   int day = dt.getDayOfMonth();

   File f = new File(fileDokument.getFileNazwa());

   String operator = produkt.getOperatorProwadzacyForRolaAndDate(dateToFind, 5).toString();
   operator = operator.replaceAll("\(.*\)", "").trim();

   PdfReader reader = new PdfReader(""+fileDokument.getFileNazwaFile());
   int height = (int) reader.getPageSize(1).getHeight();
   int width = (int) reader.getPageSize(1).getWidth();
   int fontSize = getFontSizeAdjustingToScreenSize(height);
   int marginCompatibility = getMarginCompatibilityAdjustingToScreenSize(width);
   int heightBelow = getHeightBelowAdjustingToScreenSize(width);

   File outFile = File.createTempFile("pismo_", ".pdf", MainApp.tmpDir);

   PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outFile));
   BaseFont bf = BaseFont.createFont(BaseFont.TIMES_ITALIC, codingType, false);
   PdfContentByte over;

   int total = reader.getNumberOfPages() + 1;
   for (int a = 1; a < total; a++) {
       stamper.setRotateContents(false);
       over = stamper.getOverContent(a);
       over.beginText();
       over.setFontAndSize(bf,fontSize);
       over.setTextMatrix(marginCompatibility, heightBelow);
       over.showText("Za zgodność z oryginałem Radca Prawny " + operator + ", Wrocław, dnia " + df.format(day) + "-" + df.format(month) + "-" + year + "r.  .................. (podpis)");  
       over.endText();
   }
   stamper.close();
   MainApp.openFile(outFile);

}

我的想法是缩放 pdf 以使其更小并添加始终为空且不会覆盖任何文本的 TextField。您能帮忙或提供其他想法吗?

非常感谢@mkl 和@Bruno Lowagie!

最终答案:

/**
 * method to shrink pdf file
 * @param writer
 * @param stamper
 * @param reader
 * @param page
 * @param factor
 * @throws IOException 
 */
private void shrink(com.itextpdf.text.pdf.PdfStamper stamper, int page, float factor) throws IOException
{
    com.itextpdf.text.Rectangle crop = stamper.getReader().getCropBox(page);
    float diffX = crop.getRight() * (1 - factor);
    float diffY = crop.getTop() * (1 - factor);
    com.itextpdf.text.pdf.PdfDictionary pageN = stamper.getReader().getPageN(page);
    stamper.markUsed(pageN);
    com.itextpdf.text.pdf.PdfArray ar = null;
    com.itextpdf.text.pdf.PdfObject content = com.itextpdf.text.pdf.PdfReader.getPdfObject(pageN.get(com.itextpdf.text.pdf.PdfName.CONTENTS), pageN);
    if(content == null)
        return;
    if(content.isArray())
    {
        ar = new com.itextpdf.text.pdf.PdfArray((com.itextpdf.text.pdf.PdfArray)content);
        pageN.put(com.itextpdf.text.pdf.PdfName.CONTENTS, ar);
    }
    else if(content.isStream())
    {
        ar = new com.itextpdf.text.pdf.PdfArray();
        ar.add(pageN.get(com.itextpdf.text.pdf.PdfName.CONTENTS));
        pageN.put(com.itextpdf.text.pdf.PdfName.CONTENTS, ar);
    }
    else
        return;
    com.itextpdf.text.pdf.ByteBuffer out_p = new com.itextpdf.text.pdf.ByteBuffer();
    out_p.append(factor).append(" 0 0 ").append(factor).append(' ').append(diffX).append(" ").append(diffY).append(" cm ");
    com.itextpdf.text.pdf.PdfStream stream = new com.itextpdf.text.pdf.PdfStream(out_p.toByteArray());
    ar.addFirst(stamper.getWriter().addToBody(stream).getIndirectReference());
    out_p.reset();
}

/*
* method adding box with "Za zgodnosc..." on the bottom of the page
*/
private void addBoxToPage(com.itextpdf.text.pdf.PdfReader reader, int page, float factor, com.itextpdf.text.pdf.PdfStamper stamper, String operator) throws com.itextpdf.text.DocumentException {
    DecimalFormat df = new DecimalFormat("00");
    DateTime dt = new DateTime();
    int year = dt.getYear();
    int month = dt.getMonthOfYear();
    int day = dt.getDayOfMonth();
    com.itextpdf.text.Rectangle box = reader.getCropBox(page);
    box.setTop(box.getTop() - factor * box.getHeight());
    com.itextpdf.text.pdf.PdfContentByte cb = stamper.getOverContent(page);
    cb.setColorFill(BaseColor.YELLOW);
    cb.setColorStroke(BaseColor.RED);
    cb.rectangle(box.getLeft(), box.getBottom(), box.getWidth(), box.getHeight());
    cb.fillStroke();
    cb.setColorFill(BaseColor.BLACK);
    ColumnText ct = new ColumnText(cb);
    ct.addElement(new Paragraph("Za zgodność z oryginałem Radca Prawny " + operator + ", Wrocław, dnia " + df.format(day) + "-" + df.format(month) + "-" + year + "r.  .................. (podpis)"));
    ct.setSimpleColumn(box);
    ct.go();
}

我就是这样称呼它的

   int total = reader.getNumberOfPages() + 1;
   for (int a = 1; a < total; a++) {
       shrink(stamper, a, factor);
       addBoxToPage(reader, a, factor, stamper, operator);
   }