itextpdf生成pdf,html转pdf,pdf转图片

* 利用iText五步创建一个PDF文件:
* 第一步,创建一个 iTextSharp.text.Document对象的实例:Document document = new Document();
* 第二步,为该Document创建一个Writer实例:PdfWriter.getInstance(document, new FileStream("demo.pdf", FileMode.Create));
* 第三步,打开当前Document document.Open();
* 第四步,为当前Document添加内容: document.Add(new Paragraph("Hello World"));
* 第五步,关闭Document  document.Close();

主要涉及的类有Document,Paragraph,Font,PdfPTable,PdfPCell。具体涉及的方法参数比较多,需要自己多尝试体会。如果内容是中文的话,需要注意设置下编码,否则内容不显示

    /**
     * 获取支持中文编码的Font
     *
     * @param size
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static Font getPdfChineseFont(int size) throws IOException, DocumentException {
        BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        Font fontChinese = new Font(bfChinese, size, Font.NORMAL);
        return fontChinese;
    }

依赖的JAR

 <!--itextpdf  生成pdf -->    
<dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf.tool</groupId>
            <artifactId>xmlworker</artifactId>
            <version>5.5.13</version>
        </dependency>

<!-- pdf转图片 -->
  <dependency>
            <groupId>org.icepdf.os</groupId>
            <artifactId>icepdf-core</artifactId>
            <version>6.1.2</version>
        </dependency>

1 ItemxtPdf生成pdf的demo

package org.springblade.modules.lecoffee.utils;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

@Component
public class ItextPdfUtilsDemo {

    /**
     * 利用iText五步创建一个PDF文件:
     * 第一步,创建一个 iTextSharp.text.Document对象的实例:Document document = new Document();
     * 第二步,为该Document创建一个Writer实例:PdfWriter.getInstance(document, new FileStream("demo.pdf", FileMode.Create));
     * 第三步,打开当前Document document.Open();
     * 第四步,为当前Document添加内容: document.Add(new Paragraph("Hello World"));
     * 第五步,关闭Document  document.Close();
     */
    public static void createPdf2() throws Exception {

        // 基本设置
        FileOutputStream fos = new FileOutputStream("D:\\F\\down\\demo.pdf");
        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(document, fos);
        writer.setViewerPreferences(PdfWriter.PageModeUseThumbs);

        //设置纸张大小
        document.setPageSize(PageSize.A4);
        document.open();
        document = setHeaderPic(document, "C:\\uploadFiles\\logo.jpg");
        setHeader(document);
        //手动新页面
        document.newPage();
        // table 列宽--这里是四列
        float[] widths = {131, 233, 92, 69};
        PdfPTable table = new PdfPTable(widths);
        // A4的595减去两个边距35*2
        table.setTotalWidth(525);
        // 固定table的宽度
        table.setLockedWidth(true);
        table.setHorizontalAlignment(Element.ALIGN_CENTER);
        String[] colArr = {"套餐类型", "套餐明细", "费用", "数量"};
        String[][] datas = {{"套餐1", "明细1", "费用1", "数量1"}, {"套餐2", "明细2", "费用2", "数量2"}, {"套餐3", "明细3", "费用3", "数量3"}};

        /**
         * table基本组成是cell
         * addCell(PdfCell cell) 方法会将一个个的cell依次加入到table中,添加到最后一列后会自动换行
         */
        for (int i = 0; i < colArr.length; i++) {
            PdfPCell pdfCell = new PdfPCell(); //表格的单元格
            pdfCell.setMinimumHeight(30);//设置表格行高
            pdfCell.setHorizontalAlignment(Element.ALIGN_CENTER);
            pdfCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            //左右侧边框不显示
            pdfCell.disableBorderSide(PdfPCell.LEFT);
            pdfCell.disableBorderSide(PdfPCell.RIGHT);
            // 设置边框样式,粗细,背景色
            // pdfCell.setBorder(PdfPCell.TOP);
            pdfCell.setBorderWidth(1);
            pdfCell.setBorderColor(new BaseColor(200, 200, 200));
            // 背景色
            //    pdfCell.setBackgroundColor(new BaseColor(68,114,196));

            //文本样式
            Font font = getPdfChineseFont(12);
            font.setSize(12);
            font.setStyle(Font.BOLD);
            Paragraph paragraph = new Paragraph(colArr[i], font);
            pdfCell.setPhrase(paragraph);
            table.addCell(pdfCell);
        }
        for (int i = 0; i < datas.length; i++) {
            for (int j = 0; j < datas[i].length; j++) {
                PdfPCell pdfCell = new PdfPCell();
                pdfCell.setHorizontalAlignment(Element.ALIGN_CENTER);
                pdfCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                pdfCell.setBackgroundColor(new BaseColor(0xdd7e6b));
                pdfCell.setBorderWidthTop(0.1f);
                pdfCell.setBorderWidthBottom(0.1f);
                pdfCell.setBorderWidthLeft(0.1f);
                pdfCell.setBorderWidthRight(0.1f);
                pdfCell.setBorderColorBottom(new BaseColor(0x674ea7));
                pdfCell.setBorderColorLeft(new BaseColor(0x674ea7));
                pdfCell.setBorderColorRight(new BaseColor(0x674ea7));
                pdfCell.setBorderColorTop(new BaseColor(0x674ea7));
                Font font = getPdfChineseFont(12);
                Paragraph paragraph = new Paragraph(datas[i][j], font);
                pdfCell.setPhrase(paragraph);
                table.addCell(pdfCell);
            }
        }

        //添加图片,添加的图片需要提供本地地址
        byte[] bt = FileUtils.readFileToByteArray(new File("D:\\F\\down/back.jpg"));
        PdfPCell pdfCell = new PdfPCell();
        pdfCell.setImage(Image.getInstance(bt));//插入图片
        table.addCell(pdfCell);
        table.addCell(new PdfPCell());
        table.addCell(new PdfPCell());
        table.addCell(new PdfPCell());

        // 合并单元格
        PdfPCell pdfCell2 = new PdfPCell();
        pdfCell2.setMinimumHeight(30);
        pdfCell2.setHorizontalAlignment(Element.ALIGN_CENTER);
        pdfCell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
        Font font = getPdfChineseFont(12);
        pdfCell2.setRowspan(1);
        pdfCell2.setColspan(4);
        //  pdfCell2.setBorder(pdfCell2.BOTTOM+PdfPCell.LEFT);
        pdfCell2.setBorderWidth(2);
        pdfCell2.setHorizontalAlignment(Element.ALIGN_RIGHT);
        Paragraph paragraph = new Paragraph("总价:4896 元\n仅首次", font);
        pdfCell2.setPhrase(paragraph);
        table.addCell(pdfCell2);
        document.add(table);
        document.close();
    }

    public static Document setHeaderPic(Document document, String mImgPath) throws Exception {
        Image tImgCover = Image.getInstance(mImgPath );
        /* 设置图片的位置 */
        tImgCover.setAbsolutePosition(440, 772);
        /* 设置图片的大小 */
        tImgCover.scaleAbsolute(80, 39);
        document.add(tImgCover);
        return document;
    }

    public static Document setHeader(Document document) throws Exception {
        Paragraph title = new Paragraph();
        Font fontTile = getPdfChineseFont(16);
        fontTile.setStyle(Font.BOLD);
        title.setFont(fontTile);
        title.add("\n\n\n\n雨巷");
        title.setAlignment(Paragraph.ALIGN_CENTER);
        document.add(title);
        Paragraph content = new Paragraph();
        Font fontContent = getPdfChineseFont(12);
        content.setFont(fontContent);
        content.add("撑着油纸伞,独自 \n" +
            "彷徨在悠长、悠长 \n" +
            "又寂寥的雨巷 \n" +
            "我希望逢着 \n" +
            "一个丁香一样地 \n" +
            "结着愁怨的姑娘 ");
        content.setAlignment(Paragraph.ALIGN_CENTER);
        document.add(content);
        return document;
    }



    public static void main(String[] args) throws Exception {
        createPdf2();
    }

    /**
     * 获取支持中文编码的Font
     *
     * @param size
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static Font getPdfChineseFont(int size) throws IOException, DocumentException {
        BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        Font fontChinese = new Font(bfChinese, size, Font.NORMAL);
        return fontChinese;
    }
}

结果:

2 html 生成pdf,有几个注意的点。

2.1 标签语法比较严格,不能有不完整的标签"<div>",“<img>”都不行。需要改成"<div></div>"和"<img/>"

2.2 不能引用外部样式和js,所有的代码最好在body标签内;

2.3 有些语法单位不支持或者不起作用。

2.4 不同的标签在生成pdf后处理方式可能不一致比如 <p>hello</p>和<span><span>生成pdf后间距等会有出入;

整体来说,hmtl转pdf的优点就是代码相对简单,但是对于样式要求严格的场景也会比较麻烦,会有不小的出入。

1个小建议:html转pdf,最好一开始先调用一下document.newPage()这个方法,这样会避免生成的pdf第一页的间距与后面不一致的情况。然后 img标签最好设置一下高度和宽度,且图片的协议最好是https。

package org.springblade.modules.lecoffee.utils;

import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import lombok.extern.log4j.Log4j;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

@Log4j
@Component
public class Html2PdfPageDemo extends XMLWorkerFontProvider {

    public static void htmlToPDFPage(List<String> htmlString, String pdfPath) throws Exception {
        System.out.println(htmlString);
        Document document = new Document(PageSize.A4);
        PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(pdfPath));
        document.open();
        document.setMargins(0, 0, 0, 0);
        document.addAuthor("big");
        document.addCreator("q");
        document.addSubject("subject");
        document.addCreationDate();
        document.addTitle("主题");
        XMLWorkerHelper worker = XMLWorkerHelper.getInstance();
        InputStream inputStream = null;
        document.newPage();
        worker.parseXHtml(pdfWriter, document, new ByteArrayInputStream(pageHome.getBytes("UTF-8")), inputStream, Charset.forName("UTF-8"), new AsianFontProvider());
        for (String html : htmlString) {
            document.newPage();
            worker.parseXHtml(pdfWriter, document, new ByteArrayInputStream(html.getBytes("UTF-8")), inputStream, Charset.forName("UTF-8"), new AsianFontProvider());
        }

        document.close();
    }


    static String pageHome ="\t<body>\n" +
        "\t\t<style>\n" +
        "\t\t\t* {\n" +
        "\t\t\t\tmargin: 0;\n" +
        "\t\t\t\tpadding: 0;\n" +
        "\t\t\t}\n" +
        "\t\t</style>\n" +
        "\t\t<div class=\"header\" style=\"text-align: right;padding-top: 30px;padding-right: 50px;\">\n" +
        "\t\t\t<img style=\"width: 137.75px;height: 48.25px;\" src=\"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2164552727,1674393781&fm=26&gp=0.jpg\" alt=\"\" class=\"logo\" />\n" +
        "\t\t</div>\n" +
        "\t\t<br />\n" +
        "\t\t<br />\n" +
        "\t\t<div class=\"content-wrap\" style=\"padding: 0 50px;\">\n" +
        "\t\t\t<div class=\"content\">\n" +
        "\t\t\t\t<div style=\"font-size: 14px;line-height: 1;\">Are you ok? </div>\n" +
        "\t\t\t\t<br />\n" +
        "\t\t\t\t<div style=\"font-size: 14px;line-height: 1;\">How are you </div>\n" +
        "\t\t\t\t<br />\n" +
        "\t\t\t\t<div style=\"font-size: 14px;line-height: 1;\">fine thank you</div>\n" +
        "\t\t\t</div>\n" +
        "\t\t</div>\n" +
        "\t</body>";


    static String pageTable = "\t<body>\n" +
        "\t\t<style>\n" +
        "\t\t\t* {\n" +
        "\t\t\t\tmargin: 0;\n" +
        "\t\t\t\tpadding: 0;\n" +
        "\t\t\t}\n" +
        "\t\t\t\n" +
        "\t\t\ttable {\n" +
        "\t\t\t\tborder-left: none;\n" +
        "\t\t\t\tborder-right: none;\n" +
        "\t\t\t}\n" +
        "\t\t\t\n" +
        "\t\t\ttable td {\n" +
        "\t\t\t\tborder-left: none;\n" +
        "\t\t\t\tborder-right: none;\n" +
        "\t\t\t\tborder-top: 1px solid #d4d4d4;\n" +
        "\t\t\t\tfont-size: 13px;\n" +
        "\t\t\t}\n" +
        "\t\t</style>\n" +
        "\t\t<div class=\"header\" style=\"text-align: right;padding-top: 10px;padding-right: 40px;padding-bottom: 40px;\">\n" +
        "\t\t\t<img style=\"width: 137.75px;height: 48.25px;\" src=\"https://www.focus-base.com/files/pdfimg/lecoff_logo.png\" alt=\"\" class=\"logo\" />\n" +
        "\t\t</div>\n" +
        "\t\t<div class=\"scheme\" style=\"padding: 0 50px;\">\n" +
        "\t\t\t<h3 style=\"font-size: 24px;line-height: 1;\">#planName#</h3>\n" +
        "\t\t\t<br/>\n" +
        "\t\t\t<div class=\"scheme-content\">\n" +
        "\t\t\t\t<table border=\"2\" style=\"border-collapse: collapse;width: 100%;\">\n" +
        "\t\t\t\t\t<tbody>\n" +
        "\t\t\t\t\t\t<tr style=\"height: 40px;\">\n" +
        "\t\t\t\t\t\t\t<td style=\"text-align: center;\"><b>套餐类型</b></td>\n" +
        "\t\t\t\t\t\t\t<td style=\"text-align: center;\"> <b>套餐明细</b></td>\n" +
        "\t\t\t\t\t\t\t<td style=\"text-align: center;\"><b>费用</b></td>\n" +
        "\t\t\t\t\t\t\t<td style=\"text-align: center;\"><b>数量</b></td>\n" +
        "\t\t\t\t\t\t</tr>\n" +
        "\t\t\t\t\t\t<tr>\n" +
        "\t\t\t\t\t\t\t<td style=\"text-align: center;padding: 10px 0;\">\n" +
        "\t\t\t\t\t\t\t\t<img style=\"width: 100px;height: 100px;\" src=\"https://cdn.focus-base.com/pic/2547795500040808.jpg\" alt=\"\" />\n" +
        "\t\t\t\t\t\t\t\t<div style=\"padding-top: 10px;\">#mealName#</div>\n" +
        "\t\t\t\t\t\t\t</td>\n" +
        "\t\t\t\t\t\t\t<td style=\"padding: 10px 0;\">\n" +
        "\t\t\t\t\t\t\t\t#mealDetail#\n" +
        "\t\t\t\t\t\t\t</td>\n" +
        "\t\t\t\t\t\t\t<td style=\"text-align: center;\">#mealPrice#元/月(套)</td>\n" +
        "\t\t\t\t\t\t\t<td style=\"text-align: center;\">#mealAmount#</td>\n" +
        "\t\t\t\t\t\t</tr>\n" +
        "\t\t\t\t\t\t<tr>\n" +
        "\t\t\t\t\t\t\t<td style=\"text-align: center;\">#packageName#</td>\n" +
        "\t\t\t\t\t\t\t<td class=\"t-l\" style=\"padding: 10px 0;\">\n" +
        "\t\t\t\t\t\t\t\t#packageDetail#\n" +
        "\t\t\t\t\t\t\t</td>\n" +
        "\t\t\t\t\t\t\t<td style=\"text-align: center;\">#packagePrice#元/包</td>\n" +
        "\t\t\t\t\t\t\t<td style=\"text-align: center;\">#packageAmount#</td>\n" +
        "\t\t\t\t\t\t</tr>\n" +
        "\t\t\t\t\t\t<tr>\n" +
        "\t\t\t\t\t\t\t<td style=\"text-align: right;padding: 10px 0;\" colspan=\"4\">\n" +
        "\t\t\t\t\t\t\t\t<div style=\"font-weight: bold;font-size: 16px;line-height: 1;\"><b>合计:#total#元</b></div>\n" +
        "\t\t\t\t\t\t\t</td>\n" +
        "\t\t\t\t\t\t</tr>\n" +
        "\t\t\t\t\t</tbody>\n" +
        "\t\t\t\t</table>\n" +
        "\t\t\t</div>\n" +
        "\t\t</div>\n" +
        "\t</body>";

    public static void main(String[] args) throws Exception {
        System.out.println("hehehe");
        List<String>htmlList = new ArrayList<>();
        htmlList.add(pageTable);
        htmlToPDFPage(htmlList, "D:\\F\\down\\html2Pdf.pdf");
        System.out.println("hehehe");

    }


}

将生成的pdf和,html在浏览器的效果相比较的话,table的效果差距还是比较明显的

3 pdf转图片,试了好几版,发现这版效果比较满意。当然,图片是针对pdf的每一页的内容生成。

package org.springblade.modules.lecoffee.utils;

import org.icepdf.core.pobjects.Document;
import org.icepdf.core.util.GraphicsRenderingHints;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;

public class PDFToImage {

    public static void pdf2Pic(String pdfPath, String path, String fileName) throws Exception {
        Document document = new Document();
        document.setFile(pdfPath);
        //缩放比例
        float scale = 2.5f;
        //旋转角度
        float rotation = 0f;
        for (int i = 0; i < document.getNumberOfPages(); i++) {
            BufferedImage image = (BufferedImage)
                document.getPageImage(i, GraphicsRenderingHints.SCREEN, org.icepdf.core.pobjects.Page.BOUNDARY_CROPBOX, rotation, scale);
            RenderedImage rendImage = image;
            try {
                File fileDir = new File(path);
                if (!fileDir.exists()) {
                    fileDir.mkdirs();
                }
                String imgName = fileName + i + ".png";
                File file = new File(path + imgName);
                ImageIO.write(rendImage, "png", file);
            } catch (IOException e) {
                e.printStackTrace();
            }
            image.flush();
        }
        document.dispose();
    }

    public static void main(String[] args) throws Exception {
        String filePath = "D:\\F\\down\\demo.pdf";
        pdf2Pic(filePath, "D:\\F\\down\\demo\\", "12857584447386337291_");
    }
}

结果:

生成的效果还不错

 

4 关于乱码:

通过ItemxtPdf生成pdf和用pdf转img这两步,对于中文有时候会出现乱码。一般是由于代码的字体在系统找不到导致的,

linux系统下字体会放在/usr/share/fonts 这个目录下。如果目录不存在,一般需要重新安装下字体;

yum -y install fontconfig  #安装字体库:
fc-cache -fv  #刷新字体库,使新添加、安装的字体生效

windows系统的话,字体一般在这个文件夹下 C:\Windows\Fonts

5 自定义字体

如果想自定义字体,可以先把相应的字体文件放置到对应的目录下调用即可。需要修改下获取字体的代码

    public static Font getPdfChineseFontNew(int size) throws Exception {
        //默认linux字体位置
        String fontUrl = "/usr/share/fonts" + File.separator + "SimHei.ttf";
        //获取系统类型
        String os = System.getProperties().getProperty("os.name");
        if (os.startsWith("win") || os.startsWith("Win")) {
            fontUrl = "C:\\Windows\\Fonts" + File.separator + "SimHei.ttf";
        }
        BaseFont baseFont;
        try {
            baseFont = BaseFont.createFont(fontUrl, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        } catch (Exception e) {
            //默认宋体
            e.printStackTrace();
            baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        }
        return new Font(baseFont, size, Font.NORMAL, BaseColor.BLACK);
    }

 

  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
生成PDF文件换为Excel文件需要进行以下步骤: 1. 使用iTextPdf读取PDF文件中的表格数据,并将其存储在一个数据结构中,例如二维数组或列表。 2. 使用Apache POI或其他Excel库将数据写入Excel工作簿中。 3. 将Excel工作簿保存为Excel文件。 以下是一个使用iTextPdf和Apache POI将PDF文件换为Excel文件的示例代码: ``` import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.List; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.parser.PdfTextExtractor; public class PdfToExcelConverter { public static void main(String[] args) { try { // 读取PDF文件 PdfReader reader = new PdfReader(new FileInputStream("input.pdf")); // 获取第一页 String text = PdfTextExtractor.getTextFromPage(reader, 1); // 解析表格数据 List<List<String>> tableData = parseTableData(text); // 创建Excel工作簿 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); // 将表格数据写入Excel工作簿 for (int i = 0; i < tableData.size(); i++) { Row row = sheet.createRow(i); List<String> rowData = tableData.get(i); for (int j = 0; j < rowData.size(); j++) { Cell cell = row.createCell(j); cell.setCellValue(rowData.get(j)); } } // 保存Excel文件 FileOutputStream outputStream = new FileOutputStream(new File("output.xlsx")); workbook.write(outputStream); workbook.close(); System.out.println("PDF文件已成功换为Excel文件!"); } catch (Exception e) { e.printStackTrace(); } } private static List<List<String>> parseTableData(String text) { // TODO: 解析PDF中的表格数据,返回一个二维数组或列表 return null; } } ``` 请注意,这只是一个示例,你需要根据你的具体需求和PDF文件的格式对代码进行适当修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值