1.iText是一个开源的API,但是需要注意,虽然iText是开源,如果你出于商业目的使用它,仍然需要购买商业许可证。你可以从http://itextpdf.com上免费获取iText的Java类库,iText库非常强大,支持HTML、RTF、XML以及PDF文件的生产,你可以在文档中使用各种各样的字体,并且,还可以使用同样的代码生成上述不同类型的文件。iText库包含一系列接口,可以生成不同字体的PDF文件,在PDF中创建表格,添加水印等等功能。如果你的项目是maven工程的话,在pom.xml文件中添加如下依赖,即可以给自己的应用程序添加iText库支持。
2.接下来,让我们先列出几个接下来例子中要用到的重要的类,熟悉熟悉。
1. com.itextpdf.text.Document:这是iText库中最常用的类,它代表了一个pdf实例。如果你需要从零开始生成一个PDF文件,你需要使用这个Document类。首先创建(new)该实例,然后打开(open)它,并添加(add)内容,最后关闭(close)该实例,即可生成一个pdf文件。
2. com.itextpdf.text.Paragraph:表示一个缩进的文本段落,在段落中,你可以设置对齐方式,缩进,段落前后间隔等。
3. com.itextpdf.text.Chapter:表示PDF的一个章节,他通过一个Paragraph类型的标题和整形章数创建。
4. com.itextpdf.text.Font:这个类包含了所有规范好的字体,包括family of font,大小,样式和颜色,所有这些字体都被声明为静态常量。 com.itextpdf.text.List:表示一个列表。
5. com.itextpdf.text.pdf.PDFPTable:表示一个表格。
6. com.itextpdf.text.Anchor:表示一个锚,类似于HTML页面的链接。
7. com.itextpdf.text.pdf.PdfWriter:当这个PdfWriter被添加到PdfDocument后,所有添加到Document的内容将会写入到与文件或网络关联的输出流中。
8. com.itextpdf.text.pdf.PdfReader:用于读取PDF文件。
一.配置pom
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.0.6</version> </dependency> 二.PDFUtil.java工具类
/*字体SIMHEI.TTF来自于windows系统(C:\Windows\Fonts) *直接复制过来放到src下的pdfFont文件夹里 *通过相对路径进行加载 */ public static final Rectangle PAGE_SIZE = PageSize.A4;//纸张规格 public static final float MARGIN_LEFT = 50;//左边距 public static final float MARGIN_RIGHT = 50;//右边距 public static final float MARGIN_TOP = 50;//上边距 public static final float MARGIN_BOTTOM = 50;//底部边距 public static final float SPACING = 20;//行间距 public static final String ClASS_HOURS_PDF_FOLDER="学时笔记"; public static final String COURSE_PDF_FOLDER="课程学时笔记"; private Document document = null; /** * 创建导出数据的目标文档 * * @param fileName 存储文件的临时路径 * @return * @return * @throws IOException */ public String createDocument(HttpServletRequest request, HttpServletResponse response, String fileName) throws IOException { String pdfPath = request.getSession().getServletContext().getRealPath(ClASS_HOURS_PDF_FOLDER); // 如果文件夹不存在 则创建文件夹 File folder = new File(pdfPath); if (!folder.exists()) { folder.mkdirs(); } folder.createNewFile(); String path = folder.getAbsolutePath(); // 存储文件 File file = new File(path, fileName); FileOutputStream out = null; document = new Document(PAGE_SIZE, MARGIN_LEFT,MARGIN_RIGHT, MARGIN_TOP, MARGIN_BOTTOM); try { out = new FileOutputStream(file); PdfWriter.getInstance(document, out); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } // 打开文档准备写入内容 document.open(); return pdfPath; } /** * 打包时生成pdf * * <p>Title: createDocumentZip</p> * <p>Description: </p> * @time 上午9:50:25 * @param request * @param response * @param fileName * @return * @throws IOException */ public String createDocumentZip(HttpServletRequest request, HttpServletResponse response, String fileName) throws IOException { String pdfPath = request.getSession().getServletContext().getRealPath(COURSE_PDF_FOLDER); String PDF_SAVEPATH = pdfPath; // 如果文件夹不存在 则创建文件夹 File folder = new File(PDF_SAVEPATH); if (!folder.exists()) { folder.mkdirs(); } folder.createNewFile(); String path = folder.getAbsolutePath() + "/"; // 存储文件 File file = new File(path, fileName); String filePath = pdfPath; FileOutputStream out = null; document = new Document(PAGE_SIZE, MARGIN_LEFT, MARGIN_RIGHT, MARGIN_TOP, MARGIN_BOTTOM); try { out = new FileOutputStream(file); PdfWriter.getInstance(document, out); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } // 打开文档准备写入内容 document.open(); return filePath; } /** * 将章节写入到指定的PDF文档中 * * @param chapter * @return */ public void writeChapterToDoc(Chapter chapter) { try { if (document != null) { if (!document.isOpen()) document.open(); document.add(chapter); } } catch (DocumentException e) { e.printStackTrace(); } } /** * 最后关闭PDF文档 * * <p>Title: closeDocument</p> * <p>Description: </p> * @time 上午9:59:08 */ public void closeDocument() { if (document != null) { document.close(); } } /** * 创建PDF文档中的章节 * * @param title 章节标题 * @param chapterNum 章节序列号 * @param alignment 0表示align=left,1表示align=center * @param numberDepth 章节是否带序号 * 设值=1 表示带序号 * 1.章节一; * 1.1小节一..., * 设值=0表示不带序号 * @param font 字体格式 * @return Chapter章节 */ public static Chapter createChapter(String title, int chapterNum, int alignment, int numberDepth, Font font) { Paragraph chapterTitle = new Paragraph(title, font); chapterTitle.setAlignment(alignment); Chapter chapter = new Chapter(chapterTitle, chapterNum); chapter.setNumberDepth(numberDepth); return chapter; } /** * 创建某指定章节下的小节 * * @param chapter 指定章节 * @param title 小节标题 * @param font 字体格式 * @param numberDepth 小节是否带序号 * 设值=1 表示带序号 * 1.章节一; * 1.1小节一..., * 设值=0表示不带序号 * @return * section在指定章节后追加小节 */ public static Section createSection(Chapter chapter, String title, Font font, int numberDepth) { Section section = null; if (chapter != null) { Paragraph sectionTitle = new Paragraph(title, font); sectionTitle.setSpacingBefore(SPACING); section = chapter.addSection(sectionTitle); section.setNumberDepth(numberDepth); } return section; } /** * 向PDF文档中添加的内容 * * @param text 内容 * @param font 内容对应的字体 * @return phrase 指定字体格式的内容 */ public static Phrase createPhrase(String text, Font font) { Phrase phrase = new Paragraph(text, font); return phrase; } /** * 创建列表 * * @param numbered 设置为 true 表明想创建一个进行编号的列表 * @param lettered 设置为true表示列表采用字母进行编号,为false则用数字进行编号 * @param symbolIndent * @return list */ public static List createList(boolean numbered, boolean lettered, float symbolIndent) { List list = new List(numbered, lettered, symbolIndent); return list; } /** * 创建列表中的项 * * @param content 列表项中的内容 * @param font 字体格式 * @return listItem */ public static ListItem createListItem(String content, Font font) { ListItem listItem = new ListItem(content, font); return listItem; } /** * 创造字体格式 * * @param fontname * @param size 字体大小 * @param style 字体风格 * @param color 字体颜色 * @return Font */ public static Font createFont(String fontname, float size, int style, BaseColor color) { Font font = FontFactory.getFont(fontname, size, style, color); return font; } /** * 返回支持中文的字体---常规黑体 * * @param size字体大小 * @param style字体风格 * @param color字体 颜色 * @return 字体格式 * CHARACTOR_FONT_CH_BLACK设置字体为“常规黑体” * BaseFont.IDENTITY_H水平书写 * BaseFont.EMBEDDED字体嵌入 */ public static Font createChineseFont(float size, int style, BaseColor color) { BaseFont bfChinese = null; try { String CHARACTOR_FONT_CH_BLACK = Thread.currentThread().getContextClassLoader().getResource("").getPath(); String realReadPath = CHARACTOR_FONT_CH_BLACK + "SIMHEI.TTF"; bfChinese = BaseFont.createFont(realReadPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return new Font(bfChinese, size, style, color); } /** * 下载服务器下生成的文件 * * <p>Title: download</p> * <p>Description: </p> * @time 下午2:51:34 * @param path * @param response */ public static void download(String path, HttpServletResponse response) { InputStream in = null; OutputStream out = null; try { File file = new File(path); /* 读取要下载的文件,保存到文件输入流 */ in = new FileInputStream(file); /* 设置响应头,控制浏览器下载该文件 */ response.setCharacterEncoding("UTF-8"); response.setContentType("application/octet-stream"); response.setHeader("Content-disposition", "attachment; filename=" + new String(file.getName().getBytes("UTF-8"), "ISO8859-1")); /* 创建缓冲输出流 */ out = new BufferedOutputStream(response.getOutputStream()); /* 定义缓冲区大小,开始读写 */ byte buffer[] = new byte[2048]; int len = 0; while ((len = in.read(buffer)) > 0) { out.write(buffer, 0, len); } /* 刷新缓冲区,写出 */ out.flush(); } catch (IOException ex) { ex.printStackTrace(); } } /** * 删除文件夹及其下面的所有文件 * * <p>Title: deleteAll</p> * <p>Description: </p> * @time 下午4:09:03 * @param file */ public static void deleteAll(File file) { if (file.isFile() || file.list().length == 0) { file.delete(); } else { for (File f : file.listFiles()) { deleteAll(f);// 递归删除文件夹下的每一个文件 } file.delete(); // 删除文件夹 } } } 三.导出pdf
/** * <p>Title: ExprotPdf</p> * <p>Description: 学时导出笔记为pdf</p> * @time 下午4:37:09 * @param classHoursId * @return * xy */ @SuppressWarnings("static-access") @RequestMapping(value = "/exportNotePDF", method = RequestMethod.GET) public void ExprotPdf(HttpServletRequest request, HttpServletResponse response, String classHoursId) { try { PDFUtil pdfUtil = new PDFUtil(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Font chapterFont = PDFUtil.createChineseFont(12, Font.NORMAL, new BaseColor(0, 0, 0)); Font sectionFont = PDFUtil.createChineseFont(11, Font.NORMAL, new BaseColor(255, 0, 0)); Font phraseFont = PDFUtil.createChineseFont(9, Font.NORMAL, new BaseColor(0, 0, 0)); ShiroUser USER = (ShiroUser) SecurityUtils.getSubject().getPrincipal(); List<Note> noteList = noteService.findListByClassHourId(USER.getUserId(), classHoursId); ClassHours classHours = classHoursService.findById(classHoursId); String fileName = classHours.getName() + "笔记" + ".pdf"; String Path = pdfUtil.createDocument(request, response, fileName); Chapter chapter = PDFUtil.createChapter(classHours.getName(), 1, 1, 0, chapterFont); for (int i = 0; i < noteList.size(); i++) { if (!noteList.get(i).getContent().equals(null) && noteList.get(i).getContent() != "") { Date crertionTime = noteList.get(i).getCreateTime(); String date = formatter.format(crertionTime); int videoMark = noteList.get(i).getVideoPosition(); String Content = noteList.get(i).getContent(); Section section = PDFUtil.createSection(chapter, date + " " + "【视频位置:" + videoMark + "】", sectionFont, 0); Phrase phrase = PDFUtil.createPhrase(Content, phraseFont); section.add(phrase); } else { continue; } } String filePath = Path + "/" + fileName; File file = new File(Path); pdfUtil.writeChapterToDoc(chapter); pdfUtil.closeDocument(); pdfUtil.download(filePath, response); pdfUtil.deleteAll(file);// 删除下载完的文件 } catch (Exception e) { e.printStackTrace(); } }