需求是浏览器里直接将服务器上的图片文件(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