需求是浏览器里直接将服务器上的图片文件(JPG,PNG,TIF)输出PDF, TIF还可能是多页的,这里需要把TIF合并,项目是用的Spring/SpringBoot
首先引入itextpdf依赖,编辑pom.xml,增加如下dependency
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.2</version>
</dependency>
配置Controller,输出的格式是PDF,这样浏览器能认出是PDF文档
@Controller
@RequestMapping("/api")
public class ApiController {
@RequestMapping(value = "/drawings_{no}.pdf", method = RequestMethod.GET)
public String drawings(@PathVariable("no") String no, HttpServletRequest request, HttpServletResponse response) {
try {
//processDrawings就是处理输出PDF的,我们在下一个方法介绍
byte[] contents = processDrawings(no);
String filename = "drawings_" + no + ".pdf";
response.setContentType("application/pdf");
//比较关键的是Content-Disposition是inline而不是attachment,这样提示浏览器来显示文档而不是下载
response.setHeader("Content-Disposition", "inline; fileName=" + filename);
response.setContentLength(contents.length);
response.getOutputStream().write(contents);
response.getOutputStream().flush();
} catch (Exception e) {
//request.setAttribute("message", "无法输出图号为: " + no + " 的图纸" + (e.getMessage() == null ? "" : ("<br/>" + e.getMessage())));
//return "forward:/message";
throw new HttpClientErrorException(HttpStatus.NOT_FOUND);
}
return null;
}
}
下面给出itextpdf处理图像文件输出为PDF的方法,说明写到注释里了
@Override
public byte[] processDrawings(String no) throws Exception {
String keywords = no.length() > 8 ? no.substring(0, 8) : no;
String[] allowedExts = new String[]{".jpg", ".jpeg", ".tif", ".tiff"};
List<File> foundFiles;
//根据业务逻辑的规则,找出需要合并的图像文件,或者得到自己业务生成的图片
try (Stream<Path> paths = Files.find(Paths.get("/path/to/image_folder"),
10,
(filePath, fileAttr) -> {
if (fileAttr.isRegularFile()) {
String name = filePath.getFileName().toString();
if (isContainsAllowedExts(name, allowedExts)) {
return name.startsWith(keywords);
}
}
return false;
}, FileVisitOption.FOLLOW_LINKS)) {
foundFiles = paths.map(Path::toFile).sorted(Comparator.comparing(File::getName)).collect(Collectors.toList());
}
if (foundFiles.size() == 0) {//找不到
throw new FileNotFoundException("找不到图纸文件");
}
Document document = new Document();
document.setMargins(0, 0, 0, 0);
//这里我需要直接输出到ByteArrayOutputStream,如果你要把图片输出到PDF文件保存,可以使用FileOutputStream
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PdfWriter.getInstance(document, bos);
document.open();
for (File file1 : foundFiles) {
String fileName = file1.getName().toLowerCase();
if (fileName.endsWith(".tif") || fileName.endsWith(".tiff")) {
//如果是TIF图片,可能是多页,需要解析出每一页,输出到PDF里去
RandomAccessFileOrArray tifFile = new RandomAccessFileOrArray(file1.getAbsolutePath());
int numberOfPages = TiffImage.getNumberOfPages(tifFile);
for (int i = 1; i <= numberOfPages; i++) {
Image image = TiffImage.getTiffImage(tifFile, i);
document.setPageSize(new Rectangle(image.getWidth(), image.getHeight()));
document.newPage();
document.add(image);
}
} else {//其他图像文件,就直接写入到PDF里去
Image image = Image.getInstance(file1.getAbsolutePath());
document.setPageSize(new Rectangle(image.getWidth(), image.getHeight()));
document.newPage();
document.add(image);
}
}
document.close();
return bos.toByteArray();
好了,现在启动程序,浏览器里输入 http://localhost:8080/api/drawings_123.pdf 就能直接看到PDF了
如何将多个PDF合并为一个,请移步另一篇文章:https://blog.terrynow.com/2021/01/22/java-itext-pdf-merge/
文章评论
plavix cialis side effects Bemaje Cialis Biynzw Xugars Aucece buy cialis cheap Rdjuec