Itext生成PDF檔案加密與加水印
阿新 • • 發佈:2019-02-19
public class PdfConvertor { //txt原始檔案的路徑 private static final String txtFilePath = "d:/Itext/test.txt"; //生成的pdf檔案路徑 private static final String pdfFilePath = "d:/Itext/test.pdf"; //新增水印圖片路徑 private static final String imageFilePath = "D:/image/b.gif"; //生成臨時檔案字首 private static final String prefix = "tempFile"; //所有者密碼 private static final String OWNERPASSWORD = "12345678"; /** * txt檔案轉換為pdf檔案 * * @param txtFile * txt檔案路徑 * @param pdfFile * pdf檔案路徑 * @param userPassWord * 使用者密碼 * @param waterMarkName * 水印內容 * @param permission * 操作許可權 */ public static void generatePDFWithTxt(String txtFile, String pdfFile, String userPassWord, String waterMarkName, int permission) { try { // 生成臨時檔案 File file = File.createTempFile(prefix, ".pdf"); // 建立pdf檔案到臨時檔案 if (createPDFFile(txtFile, file)) { // 增加水印和加密 waterMark(file.getPath(), pdfFile, userPassWord, OWNERPASSWORD, waterMarkName, permission); } } catch (Exception e) { e.printStackTrace(); } } /** * 建立PDF文件 * * @param txtFilePath * txt檔案路徑(原始檔) * @param pdfFilePath * pdf檔案路徑(新檔案) */ private static boolean createPDFFile(String txtFilePath, File file) { // 設定紙張 Rectangle rect = new Rectangle(PageSize.A4); // 設定頁碼 HeaderFooter footer = new HeaderFooter(new Phrase("頁碼:", PdfConvertor .setChineseFont()), true); footer.setBorder(Rectangle.NO_BORDER); // step1 Document doc = new Document(rect, 50, 50, 50, 50); doc.setFooter(footer); try { FileReader fileRead = new FileReader(txtFilePath); BufferedReader read = new BufferedReader(fileRead); // 設定pdf檔案生成路徑 step2 PdfWriter.getInstance(doc, new FileOutputStream(file)); // 開啟pdf檔案 step3 doc.open(); // 例項化Paragraph 獲取寫入pdf檔案的內容,呼叫支援中文的方法. step4 while (read.ready()) { // 新增內容到pdf(這裡將會按照txt檔案的原始樣式輸出) doc.add(new Paragraph(read.readLine(), PdfConvertor .setChineseFont())); } // 關閉pdf檔案 step5 doc.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 在pdf檔案中新增水印 * * @param inputFile * 原始檔案 * @param outputFile * 水印輸出檔案 * @param waterMarkName * 水印名字 */ private static void waterMark(String inputFile, String outputFile, String userPassWord, String ownerPassWord, String waterMarkName, int permission) { try { PdfReader reader = new PdfReader(inputFile); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream( outputFile)); // 設定密碼 stamper.setEncryption(userPassWord.getBytes(), ownerPassWord .getBytes(), permission, false); BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); int total = reader.getNumberOfPages() + 1; Image image = Image.getInstance(imageFilePath); image.setAbsolutePosition(200, 400); PdfContentByte under; int j = waterMarkName.length(); char c = 0; int rise = 0; for (int i = 1; i < total; i++) { rise = 500; under = stamper.getUnderContent(i); // 新增圖片 // under.addImage(image); under.beginText(); under.setColorFill(Color.CYAN); under.setFontAndSize(base, 30); // 設定水印文字字型傾斜 開始 if (j >= 15) { under.setTextMatrix(200, 120); for (int k = 0; k < j; k++) { under.setTextRise(rise); c = waterMarkName.charAt(k); under.showText(c + ""); rise -= 20; } } else { under.setTextMatrix(180, 100); for (int k = 0; k < j; k++) { under.setTextRise(rise); c = waterMarkName.charAt(k); under.showText(c + ""); rise -= 18; } } // 字型設定結束 under.endText(); // 畫一個圓 // under.ellipse(250, 450, 350, 550); // under.setLineWidth(1f); // under.stroke(); } stamper.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 設定中文 * * @return Font */ private static Font setChineseFont() { BaseFont base = null; Font fontChinese = null; try { base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED); fontChinese = new Font(base, 12, Font.NORMAL); } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return fontChinese; } public static void main(String[] args) { generatePDFWithTxt(txtFilePath, pdfFilePath, "123", "www.emice.com", 16); } }
bcprov-jdk15-139.jar 加密時用到。 iText-2.1.2u.jar Itext包。 iTextAsian.jar 在匯入中文是要用到。
另:普通生成pdf程式碼
package test; import java.awt.Color; import java.io.FileOutputStream; import com.lowagie.text.Cell; import com.lowagie.text.Chapter; import com.lowagie.text.Document; import com.lowagie.text.Font; import com.lowagie.text.FontFactory; import com.lowagie.text.List; import com.lowagie.text.ListItem; import com.lowagie.text.PageSize; import com.lowagie.text.Paragraph; import com.lowagie.text.Section; import com.lowagie.text.Table; import com.lowagie.text.pdf.PdfWriter; public class ITextTest { public static void main(String[] args) { try { /** * 例項化文件物件 第一個引數是頁面大小。接下來的引數分別是左、右、上和下頁邊距。但是還沒有定義該文件的型別。 * 它取決於所建立的寫入器的型別。對於我們的示例,選擇了com.lowagie.text.pdf.PdfWriter。 其他寫入器為 * HtmlWriter、RtfWriter、XmlWriter 等等。它們的名稱解釋了它們的實際用途。 */ Document document = new Document(PageSize.A4, 50 , 50 , 50 , 50 ); /** * 建立 PdfWriter 物件,第一個引數是對文件物件的引用,第二個引數是檔案的實際名稱,在該名稱中還會給出其輸出路徑。 */ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream( " D:\\ITextTest.pdf " )); /** * 開啟文件以寫入內容 */ document.open(); /** * 現在,將在文件的第一頁上新增一些文字。通過 com.lowagie.text.Paragraph * 來新增文字。可以用文字及其預設的字型、顏色、大小等等設定來建立一個預設段落。 * 或者,也可以設定自己的字型。下面讓我們來看看這兩種做法。 * * 建立段落物件 * */ document.add( new Paragraph( " First page of the document. " )); document .add( new Paragraph( " Some more text on the first page with different color and font type. " , FontFactory.getFont(FontFactory.COURIER, 14 , Font.BOLD, new Color( 255 , 150 , 200 )))); /** * 您已經看到了如何向 PDF文件中新增純文字。 接下來,需要向文件中新增一些複雜的元素。我們開始建立一個新的章節。 * 章節是一個特殊的小節,預設情況下,章節從一個新的頁面開始,並顯示一個預設的編號。 * * 建立章節物件 */ Paragraph title1 = new Paragraph( " Chapter 1 " , FontFactory.getFont( FontFactory.HELVETICA, 18 , Font.BOLDITALIC, new Color( 0 , 0 , 255 ))); Chapter chapter1 = new Chapter(title1, 1 ); chapter1.setNumberDepth( 0 ); /** * 在上面的程式碼中,建立了一個新的章節物件,chapter1,其標題為 “This is Chapter 1”,將編號級別設為 0 * 就不會在頁面上顯示章節編號。 * * 小節是章節的子元素。在下面的程式碼中,建立了一個標題為 “This is Section 1 in Chapter 1” * 的小節。為在該小節下新增一些文字,建立了另一個段落物件,someSectionText,並將其新增到小節物件中。 * * 建立小節物件 * */ Paragraph title11 = new Paragraph( " This is Section 1 in Chapter 1 " , FontFactory.getFont(FontFactory.HELVETICA, 16 , Font.BOLD, new Color( 255 , 0 , 0 ))); Section section1 = chapter1.addSection(title11); Paragraph someSectionText = new Paragraph( " This text comes as part of section 1 of chapter 1. " ); section1.add(someSectionText); someSectionText = new Paragraph( " Following is a 3 X 2 table. " ); section1.add(someSectionText); /** * 在新增表格之前,我們先看一下文件的樣子。新增下面兩行程式碼以關閉文件,然後編譯並執行程式以生成 PDF * 文件:document.add(chapter1);document.close(); */ /** * 接下來,建立一個表格物件。建立一個包含行列矩陣的表格。行中的單元格可以跨多個列。同樣地,列中的單元格也可以跨多個行。 因此,一個 * 3 x 2 的表格實際上不一定有 6 個單元格。 * * 建立表格物件 */ Table t = new Table( 3 , 2 ); t.setBorderColor( new Color( 220 , 255 , 100 )); t.setPadding( 5 ); t.setSpacing( 5 ); t.setBorderWidth( 1 ); Cell c1 = new Cell( " header1 " ); t.addCell(c1); c1 = new Cell( " Header2 " ); t.addCell(c1); c1 = new Cell( " Header3 " ); t.addCell(c1); t.addCell( " 1.1 " ); t.addCell( " 1.2 " ); t.addCell( " 1.3 " ); section1.add(t); /** * 在上面的程式碼中,建立了一個表格物件,t,它有三列、兩行。然後設定表格的邊框顏色。填充用於設定單元格中文字間的間隔以及單元格的邊界。 * 間隔指的是相鄰單元格間的邊界。接下來,將建立三個單元格物件,每個單元格中的文字都各不相同。接下來,將它們新增到表格中。 * 將它們新增到第一行中,從第一列開始,移到同一行中的下一列。一旦該行建立完成,就將下一個單元格新增到下一行的第一列中。 * 也可以通過只提供單元格的文字將單元格新增到表格中,例如,t.addCell("1.1");。最後,將表格物件新增到小節物件中。 * * 最後,我們來看一下如何將列表新增到 PDF 文件中。列表包含一定數量的 * ListItem。可以對列表進行編號,也可以不編號。將第一個引數設定為 true 表明想建立一個要進行編號的列表。 * * 建立列表物件 */ List l = new List( true , true , 10 ); l.add( new ListItem( " First item of list " )); l.add( new ListItem( " Second item of list " )); section1.add(l); /** * 我們已經向 chapter1 物件中添加了所需的物件。因此,已經沒有其他要新增到 chapter1 中的元素了,現在可以將 * chapter1 新增到主 document 中了。與在示例應用程式中所做的一樣,還要在這時關閉文件物件。 * * 向主文件中新增章節 */ document.add(chapter1); document.close(); } catch (Exception e2) { System.out.println(e2.getMessage()); } /** * 您已經看到了一些生成 PDF 的基本元素。iText的美妙之處是相同元素的語法可以供不同型別的寫入器使用。 * 而且,寫入器的輸出可以重定向到控制檯(當寫入器型別是 XML 和 HTML時)、 * servlet 的輸出流(在對 PDF 文件的 Web 請求作出響應時)或者是其他型別的OutputStream。 * 當響應相同,但其型別隨所請求的是 PDF、RTF、HTML 或 XML 文件而有所不同時,使用 iText是非常方便的。 * iText 允許使用者建立水印,對文件進行加密以及設定其他輸出細節。 */ } }