有没有我可以使用的开源库?
iText 可以帮助你。
实际上并不是将 PNG 转换为 PDF,而是在 PDF 中创建一个包含 PNG 的文件。
以下是简单的示例:
Document document = new Document(PageSize.A4, 20, 20, 20, 20);
PdfWriter.getInstance(document, new FileOutputStream("C:/test.pdf"));
document.open();
Image image = Image.getInstance(getClass().getResource("/logo.png"));
document.add(image);
document.close();
/**
* Converts arbitrary image file to PDF
* https://dev59.com/CWsy5IYBdhLWcg3wtwa9#42937466
* @param imageFile contents of JPEG or PNG file
* @param outputStream stream to write out pdf, always closed after this method execution.
* @throws IOException when there' an actual exception or image is not valid
*/
public static void imageToPdf(byte[] imageFile, OutputStream outputStream) throws IOException {
try {
Image image;
try {
image = Image.getInstance(imageFile);
} catch (BadElementException bee) {
throw new IOException(bee);
}
//See https://dev59.com/y3M_5IYBdhLWcg3wcSx_
Rectangle A4 = PageSize.A4;
float scalePortrait = Math.min(A4.getWidth() / image.getWidth(),
A4.getHeight() / image.getHeight());
float scaleLandscape = Math.min(A4.getHeight() / image.getWidth(),
A4.getWidth() / image.getHeight());
// We try to occupy as much space as possible
// Sportrait = (w*scalePortrait) * (h*scalePortrait)
// Slandscape = (w*scaleLandscape) * (h*scaleLandscape)
// therefore the bigger area is where we have bigger scale
boolean isLandscape = scaleLandscape > scalePortrait;
float w;
float h;
if (isLandscape) {
A4 = A4.rotate();
w = image.getWidth() * scaleLandscape;
h = image.getHeight() * scaleLandscape;
} else {
w = image.getWidth() * scalePortrait;
h = image.getHeight() * scalePortrait;
}
Document document = new Document(A4, 10, 10, 10, 10);
try {
PdfWriter.getInstance(document, outputStream);
} catch (DocumentException e) {
throw new IOException(e);
}
document.open();
try {
image.scaleAbsolute(w, h);
float posH = (A4.getHeight() - h) / 2;
float posW = (A4.getWidth() - w) / 2;
image.setAbsolutePosition(posW, posH);
image.setBorder(Image.NO_BORDER);
image.setBorderWidth(0);
try {
document.newPage();
document.add(image);
} catch (DocumentException de) {
throw new IOException(de);
}
} finally {
document.close();
}
} finally {
outputStream.close();
}
}
在pom.xml文件中,如果您尚未使用iText,则可以使用其中一个免费的iText分支。
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf</artifactId>
<version>1.0.1</version>
</dependency>
import java.io.FileOutputStream;
//com.lowagie... old version
//com.itextpdf... recent version
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.Image;
public class ImageToPDF {
public static void main(String ... args) {
Document document = new Document();
String input = "c:/temp/capture.png"; // .gif and .jpg are ok too!
String output = "c:/temp/capture.pdf";
try {
FileOutputStream fos = new FileOutputStream(output);
PdfWriter writer = PdfWriter.getInstance(document, fos);
writer.open();
document.open();
document.add(Image.getInstance(input));
document.close();
writer.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
为了简化现代网页,PNG或JPEG格式的页面可以通过命令行转换为单个或多个页面的PDF。
通过将图像设置为默认宽度或高度,或设置为保持任何比例,只需几行命令行文本即可输出PDF。非常容易在简单的记事本或复杂的IDE中进行模板设计。
对于转换,Chrome-headless对于一个页面可能比释放回车键更快,但处理4000张图片需要更长时间。
其他库可以用于更复杂的操作作为后处理。然而,除非添加额外的CSS,否则Chrome只会生成一个异常好的默认媒体页面。
因此,请从控制台或其他编辑器中输入以下内容:
<HTML>
<image src="01.jpg" width="100%" />
<image src="02.jpg" width="100%" />
</HTML>
运行Java shell相当于
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --headless --print-to-pdf="C:\Data\out.pdf" C:/Data/htm.htm