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();
}
}