java后台生成pdf报告

该文章的为传递一整套html内容,后台转为pdf的方法,有一个小问题是(html里写的图片无法生成出来。。不知道为啥)

1、先引入jar包

	<!-- todo html转pdf-->
		<dependency>
			<groupId>com.itextpdf.tool</groupId>
			<artifactId>xmlworker</artifactId>
			<version>5.5.1</version>
		</dependency>
		<!-- 支持中文 -->
		<dependency>
			<groupId>com.itextpdf</groupId>
			<artifactId>itext-asian</artifactId>
			<version>5.2.0</version>
		</dependency>
		<!-- 支持css样式渲染 -->
		<dependency>
			<groupId>org.xhtmlrenderer</groupId>
			<artifactId>flying-saucer-pdf-itext5</artifactId>
			<version>9.0.3</version>
		</dependency>
		<!-- todo html转pdf-->

2、编写生成pdf的语句(遗漏了一个内容的实体类,在最后面加上)

public static void htmlTopdf(String html, File file) throws Exception {
		try {
			// step 1
			Document document = new Document();
			BaseFont bfChinese;
			bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
			MyFontProvider myFontProvider = new MyFontProvider(BaseColor.BLACK, "", "", false, false, 8, 1, bfChinese);
			// step 2
			PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
			writer.setStrictImageSequence(true);
			// step 3
			document.open();
// todo 因为html无法生成图片,最后想了一个折中的办法,在pdf里生成,这个是直接通过网络路径转的
			String url=ImageBase64("https://img-blog.csdnimg.cn/24828250aeca4b38b7d2d1847ccc4df4.png");
			byte [] byteArray = Base64.getDecoder().decode(url);
			Image image2 = Image.getInstance(byteArray);
			document.add(image2);
			float currentWidth = image2.getWidth();
			float currentHeight = image2.getHeight();
			image2.scalePercent(50);
			float newWidth = image2.getWidth();
			float newHeight = image2.getHeight();
// todo --------------------也可能写错了,哈哈这段代码是从历史记录里翻出来的。不确定是不是写的有问题,懒得再找。不对的话,可以搜一下。可以肯定能实现图片这个功能
			final TagProcessorFactory tagProcessorFactory = Tags.getHtmlTagProcessorFactory();
			tagProcessorFactory.removeProcessor(HTML.Tag.IMG);

			final CssFilesImpl cssFiles = new CssFilesImpl();
			cssFiles.add(XMLWorkerHelper.getInstance().getDefaultCSS());
			final StyleAttrCSSResolver cssResolver = new StyleAttrCSSResolver(cssFiles);
			final HtmlPipelineContext hpc = new HtmlPipelineContext(new CssAppliersImpl(myFontProvider));
			hpc.setAcceptUnknown(true).autoBookmark(true).setTagFactory(tagProcessorFactory);
			final HtmlPipeline htmlPipeline = new HtmlPipeline(hpc, new PdfWriterPipeline(document, writer));
			final Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, htmlPipeline);

			final XMLWorker worker = new XMLWorker(pipeline, true);

			final Charset charset = StandardCharsets.UTF_8;
			final XMLParser xmlParser = new XMLParser(true, worker, charset);

			ByteArrayInputStream bais = new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8));
			xmlParser.parse(bais, charset);

			// step 5
			document.close();
			bais.close();
		} catch (Exception e) {
			throw new Exception(e);
		}
	}

3、网络图片转地址

rivate static String ImageBase64(String imgUrl) {
        URL url = null;
        InputStream is = null;
        ByteArrayOutputStream outStream = null;
        HttpURLConnection httpUrl = null;
        try{
            url = new URL(imgUrl);
            httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.connect();
            httpUrl.getInputStream();
            is = httpUrl.getInputStream();
 
            outStream = new ByteArrayOutputStream();
            //创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            //每次读取的字符串长度,如果为-1,代表全部读取完毕
            int len = 0;
            //使用一个输入流从buffer里把数据读取出来
            while( (len=is.read(buffer)) != -1 ){
                //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
                outStream.write(buffer, 0, len);
            }
            // 对字节数组Base64编码
            // java11与后面版本用这个
            return new Base64Util().encode(outStream.toByteArray());
            // java11之前用这个
            return new BASE64Encoder().encode(outStream.toByteArray());
        }catch (Exception e) {
            e.printStackTrace();
        }
        finally{
            if(is != null)
            {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outStream != null)
            {
                try {
                    outStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(httpUrl != null)
            {
                httpUrl.disconnect();
            }
        }
        return imgUrl;
    }

4、调用传值方法将要生成pdf的图片和内容传给2方法。对html语句要求比较严格,但是如果那个标签的结束符未写,是无法生成的。

public static void main(String[] args) {
		String content =
			"<html>\n" +
					"<head>\n" +
					"    <meta charset=\"UTF-8\"></meta>\n" +
					"    <meta name=\"viewport\" content=\"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0\"></meta>\n" +
					"    <title>ddsa</title>\n" +
					"    <style>\n" +
					"</style>\n" +
					"</head>\n" +
					"<body style=\"width=1800px;\">\n" +

					"<div>123123123</div></body>\n" +
					"</html>";
		String url="d:/ss.pdf";
		File file = new File(url);


		try {
			htmlTopdf(content, file);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

最终样式:(图片太大我给注释了)

5、MyFontProvider的实体类


import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontProvider;
import com.itextpdf.text.pdf.BaseFont;

public class MyFontProvider implements FontProvider {
    private BaseColor bc;
    private String fontname;
    private String encoding;
    private boolean embedded;
    private boolean cached;
    private float size;
    private int style;
    private BaseFont baseFont;

    public MyFontProvider() {
    }

    public BaseColor getBc() {
        return bc;
    }

    public void setBc(BaseColor bc) {
        this.bc = bc;
    }

    public String getFontname() {
        return fontname;
    }

    public void setFontname(String fontname) {
        this.fontname = fontname;
    }

    public String getEncoding() {
        return encoding;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    public boolean isEmbedded() {
        return embedded;
    }

    public void setEmbedded(boolean embedded) {
        this.embedded = embedded;
    }

    public boolean isCached() {
        return cached;
    }

    public void setCached(boolean cached) {
        this.cached = cached;
    }

    public float getSize() {
        return size;
    }

    public void setSize(float size) {
        this.size = size;
    }

    public int getStyle() {
        return style;
    }

    public void setStyle(int style) {
        this.style = style;
    }

    public BaseFont getBaseFont() {
        return baseFont;
    }

    public void setBaseFont(BaseFont baseFont) {
        this.baseFont = baseFont;
    }

    public MyFontProvider(BaseColor bc, String fontname, String encoding, boolean embedded, boolean cached, float size,
                          int style, BaseFont baseFont) {
        super();
        this.bc = bc;
        this.fontname = fontname;
        this.encoding = encoding;
        this.embedded = embedded;
        this.cached = cached;
        this.size = size;
        this.style = style;
        this.baseFont = baseFont;
    }

    public Font getFont(String arg0, String arg1, boolean arg2, float arg3, int arg4, BaseColor arg5) {
        Font font = null;
        if (baseFont == null) {
            font = new Font();
        } else {
            font = new Font(baseFont);
        }
        font.setColor(arg5);
        font.setFamily(fontname);
        font.setSize(size);
        font.setStyle(arg4);
        return font;
    }

    public boolean isRegistered(String arg0) {
        // TODO Auto-generated method stub
        return true;
    }

}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你可以通过以下步骤实现: 1. 在后台接收到pdf二进制流文件后,将其保存为byte[]数组。 2. 将byte[]数组转换为InputStream对象。 3. 使用PdfBox库(或其他pdf处理库)将InputStream对象转换PDF文档对象(PDDocument)。 4. 根据需要,对PDF文档进行修改(例如添加水印、修改内容等)。 5. 将修改后的PDF文档保存到本地文件系统。 下面是一个简单的Java代码示例,演示如何将接收到的pdf二进制流文件保存到本地: ```java import org.apache.pdfbox.pdmodel.PDDocument; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; public class PdfFileHandler { public void savePdf(byte[] pdfBytes, String savePath) throws IOException { // 将byte[]数组转换为InputStream对象 InputStream inputStream = new ByteArrayInputStream(pdfBytes); // 使用PdfBox库将InputStream对象转换为PDDocument对象 PDDocument document = PDDocument.load(inputStream); // 将PDDocument对象保存为本地文件 document.save(new File(savePath)); // 关闭PDDocument对象 document.close(); } public static void main(String[] args) throws IOException { byte[] pdfBytes = // 从请求中获取pdf二进制流文件 String savePath = "C:/temp/test.pdf"; // 保存路径 PdfFileHandler handler = new PdfFileHandler(); handler.savePdf(pdfBytes, savePath); } } ``` 请注意,本示例仅演示了最基本的保存操作。在实际使用中,您可能需要根据具体的需求进行修改和扩展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值