大家好,欢迎来到IT知识分享网。
JPG图片文件格式打印实现
打印JPG图片格式的文件,本次采用的Java原生的打印方式。
public static void main(String[] argv) throws Exception {
File file = new File("E:\\a.jpg"); String printerName = "HP MFP M436 PCL6";//打印机名包含字串 PDFPrint(file,printerName); } // 传入文件和打印机名称 public static void JPGPrint(File file,String printerName) throws PrintException {
if (file == null) {
System.err.println("缺少打印文件"); } InputStream fis = null; try {
// 设置打印格式,如果未确定类型,可选择autosense DocFlavor flavor = DocFlavor.INPUT_STREAM.JPEG; // 设置打印参数 PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); aset.add(new Copies(1)); //份数 //aset.add(MediaSize.ISO.A4); //纸张 // aset.add(Finishings.STAPLE);//装订 aset.add(Sides.DUPLEX);//单双面 // 定位打印服务 PrintService printService = null; if (printerName != null) {
//获得本台电脑连接的所有打印机 PrintService[] printServices = PrinterJob.lookupPrintServices(); if(printServices == null || printServices.length == 0) {
System.out.print("打印失败,未找到可用打印机,请检查。"); return ; } //匹配指定打印机 for (int i = 0;i < printServices.length; i++) {
System.out.println(printServices[i].getName()); if (printServices[i].getName().contains(printerName)) {
printService = printServices[i]; break; } } if(printService==null){
System.out.print("打印失败,未找到名称为" + printerName + "的打印机,请检查。"); return ; } } fis = new FileInputStream(file); // 构造待打印的文件流 Doc doc = new SimpleDoc(fis, flavor, null); DocPrintJob job = printService.createPrintJob(); // 创建打印作业 job.print(doc, aset); } catch (FileNotFoundException e1) {
e1.printStackTrace(); } finally {
// 关闭打印的文件流 if (fis != null) {
try {
fis.close(); } catch (IOException e) {
e.printStackTrace(); } } } } }
PDF文件格式打印实现
使用Apache PDFbox来实现进行PDF文件格式的打印
1.PDF文件格式打印实现
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.6</version> </dependency>
public static void main(String[] args) throws Exception {
String pdfFile = "E:\\a.pdf";//文件路径 File file = new File(pdfFile); String printerName = "HP MFP M436 PCL6";//打印机名包含字串 print(file,printerName); } public static void PDFprint(File file ,String printerName) throws Exception {
PDDocument document = null; try {
document = PDDocument.load(file); PrinterJob printJob = PrinterJob.getPrinterJob(); printJob.setJobName(file.getName()); if (printerName != null) {
// 查找并设置打印机 //获得本台电脑连接的所有打印机 PrintService[] printServices = PrinterJob.lookupPrintServices(); if(printServices == null || printServices.length == 0) {
System.out.print("打印失败,未找到可用打印机,请检查。"); return ; } PrintService printService = null; //匹配指定打印机 for (int i = 0;i < printServices.length; i++) {
System.out.println(printServices[i].getName()); if (printServices[i].getName().contains(printerName)) {
printService = printServices[i]; break; } } if(printService!=null){
printJob.setPrintService(printService); }else{
System.out.print("打印失败,未找到名称为" + printerName + "的打印机,请检查。"); return ; } } //设置纸张及缩放 PDFPrintable pdfPrintable = new PDFPrintable(document, Scaling.ACTUAL_SIZE); //设置多页打印 Book book = new Book(); PageFormat pageFormat = new PageFormat(); //设置打印方向 pageFormat.setOrientation(PageFormat.PORTRAIT);//纵向 pageFormat.setPaper(getPaper());//设置纸张 book.append(pdfPrintable, pageFormat, document.getNumberOfPages()); printJob.setPageable(book); printJob.setCopies(1);//设置打印份数 //添加打印属性 HashPrintRequestAttributeSet pars = new HashPrintRequestAttributeSet(); pars.add(Sides.DUPLEX); //设置单双页 printJob.print(pars); }finally {
if (document != null) {
try {
document.close(); } catch (IOException e) {
e.printStackTrace(); } } } } public static Paper getPaper() {
Paper paper = new Paper(); // 默认为A4纸张,对应像素宽和高分别为 595, 842 int width = 595; int height = 842; // 设置边距,单位是像素,10mm边距,对应 28px int marginLeft = 10; int marginRight = 0; int marginTop = 10; int marginBottom = 0; paper.setSize(width, height); // 下面一行代码,解决了打印内容为空的问题 paper.setImageableArea(marginLeft, marginRight, width - (marginLeft + marginRight), height - (marginTop + marginBottom)); return paper; }
2.java 利用 pdfbox 实现PDF转为图片
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.16</version> </dependency> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>fontbox</artifactId> <version>2.0.16</version> </dependency>
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.PDFRenderer; import org.icepdf.core.exceptions.PDFException; import org.icepdf.core.exceptions.PDFSecurityException; import org.icepdf.core.pobjects.Document; import org.icepdf.core.pobjects.Page; import org.icepdf.core.util.GraphicsRenderingHints; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; public class PDF2ImageUtil {
/ * 经过测试,dpi为96,100,105,120,150,200中, * 120,150,200显示效果较为清晰,体积稳定,dpi越高图片体积越大 * 分享遇到的坑: * 1.如何解决 Linux 环境下乱码的问题:重写 UnixFontDirFinder 类,修改 Linux 环境下获取字体文件的路径,改为取项目里的字体文件(使用 pdfbox 转图片时的方法,使用 icepdf 请自行研究) * 2.如果后续遇到乱码的问题,查看日志看看缺少什么字体,然后将字体文件上传到项目的 src/main/resources/fonts 目录下即可 */ public static final float DEFAULT_DPI = 200; public static final String DEFAULT_FORMAT = "jpg"; / * pdf转图片,demo * (使用 pdfbox) * @param pdfPath PDF路径 * @imgPath img路径 * @page_end 要转换的页码,也可以定义开始页码和结束页码,根据需求自行添加 */ public static void pdfToImage(String pdfPath, String imgPath,int page_end) {
try {
//图像合并使用参数 // 总宽度 int width = 0; // 保存一张图片中的RGB数据 int[] singleImgRGB; int shiftHeight = 0; //保存每张图片的像素值 BufferedImage imageResult = null; //利用PdfBox生成图像 PDDocument pdDocument = PDDocument.load(new File(pdfPath)); PDFRenderer renderer = new PDFRenderer(pdDocument); //循环每个页码 for (int i = 0, len = pdDocument.getNumberOfPages(); i < len; i++) {
if (i==page_end) {
BufferedImage image = renderer.renderImageWithDPI(i, DEFAULT_DPI, ImageType.RGB); int imageHeight = image.getHeight(); int imageWidth = image.getWidth(); //计算高度和偏移量 //使用第一张图片宽度; width = imageWidth; //保存每页图片的像素值 imageResult = new BufferedImage(width, imageHeight, BufferedImage.TYPE_INT_RGB); //这里有高度,可以将imageHeight*len,我这里值提取一页所以不需要 singleImgRGB = image.getRGB(0, 0, width, imageHeight, null, 0, width); // 写入流中 imageResult.setRGB(0, shiftHeight, width, imageHeight, singleImgRGB, 0, width); }else i**粗体**f(i>page_end) {
continue; } } pdDocument.close(); // 写图片 ImageIO.write(imageResult, DEFAULT_FORMAT, new File(imgPath)); } catch (Exception e) {
e.printStackTrace(); } } / * 将PDF转化为图片 * (使用 pdfbox) * @param pdDocument PDF对象 * @param page_end 要转换的页码,发票一般是一页,取第一页 * @return */ public static BufferedImage pdfToImage(PDDocument pdDocument,int page_end) {
//保存每张图片的像素值 BufferedImage imageResult = null; try {
//图像合并使用参数 // 总宽度 int width = 0; // 保存一张图片中的RGB数据 int[] singleImgRGB; int shiftHeight = 0; //利用PdfBox生成图像 PDFRenderer renderer = new PDFRenderer(pdDocument); //循环每个页码 for (int i = 0, len = pdDocument.getNumberOfPages(); i < len; i++) {
if (i==page_end) {
BufferedImage image = renderer.renderImageWithDPI(i, DEFAULT_DPI, ImageType.RGB); int imageHeight = image.getHeight(); int imageWidth = image.getWidth(); //计算高度和偏移量 //使用第一张图片宽度; width = imageWidth; //保存每页图片的像素值 imageResult = new BufferedImage(width, imageHeight, BufferedImage.TYPE_INT_RGB); //这里有高度,可以将imageHeight*len,我这里值提取一页所以不需要 singleImgRGB = image.getRGB(0, 0, width, imageHeight, null, 0, width); // 写入流中 imageResult.setRGB(0, shiftHeight, width, imageHeight, singleImgRGB, 0, width); }else if(i>page_end) {
continue; } } pdDocument.close(); } catch (Exception e) {
e.printStackTrace(); } return imageResult; } / * 将pdf转为图片(不建议使用) *(使用 icepdf) * @param pdfContent pdf数据流 * @param zoom 缩略图显示倍数,1表示不缩放,0.3则缩小到30%,倍数越大越清晰,图片也越大,转换得也越慢 * @return * @throws PDFException * @throws PDFSecurityException * @throws IOException */ public static ByteArrayOutputStream tranferPDF2Img(byte[] pdfContent, float zoom) throws PDFException, PDFSecurityException, IOException {
Document document = null; float rotation = 0f;// 旋转角度 if(pdfContent == null){
throw new RuntimeException("pdf文件内容不能为空"); } ByteArrayInputStream bin = new ByteArrayInputStream(pdfContent); ByteArrayOutputStream out = new ByteArrayOutputStream(); document = new Document(); document.setInputStream(bin, null); int maxPages = document.getPageTree().getNumberOfPages(); for (int i = 0; i < maxPages; i++) {
BufferedImage img = null; try {
img = (BufferedImage) document.getPageImage(i, GraphicsRenderingHints.SCREEN, Page.BOUNDARY_CROPBOX, rotation, zoom); } catch (InterruptedException e) {
e.printStackTrace(); } try {
ImageIO.write(img, DEFAULT_FORMAT, out); } catch (IOException e) {
throw new RuntimeException("pdf内容读取异常", e); } img.flush(); } return out; } }
获取到流后调用方法转为图片返回给前台
// 开发中可以直接读取文件,测试、生产时代码中改为加载 InputStream PDDocument pdDocument = PDDocument.load(new File("F:\\destop\\1.pdf")); BufferedImage bufferedImage= PDF2ImageUtil.pdfToImage(pdDocument, 0); ImageIO.write(bufferedImage, "jpg", outImage);
想想还是研究研究 pdfbox 的源码吧,分析后发现它是根据不同系统来读取字体的文件夹的,然后一个同事建议我重写读写 Linux 系统文件的类,指向我们项目的文件夹,然后在项目新建一个文件夹来存放需要的字体。
Linux 读取的是以下这几个目录: “/usr/local/fonts”, “/usr/local/share/fonts”, “/usr/share/fonts”, “/usr/X11R6/lib/X11/fonts”
MAC: “/Library/Fonts/”, “/Library/Fonts/”, “/System/Library/Fonts/”, “/Network/Library/Fonts/”
Windows: C:\Windows\Fonts
说干就干,将目录指向我新建的font文件夹,果然ok了。 需要注意的是,后面如果pdf有用到新的字体,就需要将对应的字体下载下来,放到该目录下。
package org.apache.fontbox.util.autodetect; import com.ai.ecs.h5.view.common.pdf.PdfController; public class UnixFontDirFinder extends NativeFontDirFinder {
public UnixFontDirFinder() {
} protected String[] getSearchableDirectories() {
return new String[]{
PdfController.class.getResource("/").getPath()+"/fonts/"}; } }
3.java 往 pdf 插入数据 (pdfbox+poi)
指定页码插入/替换
pdfbox好像没有专门提供这个方法,但是现有的方法多重组合起来也能实现这个功能,
需求:一个pdf文件A有10页,现在想在第6页插入一页新的pdf文件B,插入完成后整个pdf文件A变成11页。
思路1(插入):
先将这个10的pdf拆分成10个1页的pdf,按顺序放好,文件名分别是:1.pdf、2.pdf…10.pdf。再拆分到第6页的时候将文件B放进来,重命名问6.pdf,原本pdf文件A里面的第6页重命名为7.pdf,依次后推,最后的得到的1.pdf—–>11.pdf一共11个文件
然后使合并功能将这个11个pdf按顺序合并。
思路2(替换):
在插入的基础上,拆分的时候将pdf文件A里面的第6个页丢弃,使用新的页面来代替它命名6.pdf,然后合并就完事了。
1.pom <!--pdfbox--> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox-tools</artifactId> <version>2.0.25</version> </dependency> <dependency> <groupId>net.sf.cssbox</groupId> <artifactId>pdf2dom</artifactId> <version>2.0.1</version> </dependency> <!--poi--> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.10</version> </dependency> <dependency> <groupId>com.itextpdf.tool</groupId> <artifactId>xmlworker</artifactId> <version>5.5.10</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>3.15</version> </dependency> 2.实现方法 /from fhadmin.cn * 指定页码插入页 * @param filename1 源pdf路径 * @param filename2 需要插入的pdf路径 * @param number 插入的页码 * @param newfilename 全新pdf的路径 * @throws Exception */ public void insertPage(String filename1,String filename2,int number,String newfilename,String tempPath) throws Exception {
PDDocument pdf1 = PDDocument.load(new File(filename1)); PDDocument pdf2 = PDDocument.load(new File(filename2)); //1、将第一个pdf按页码全部拆开 Splitter splitter = new Splitter(); List<PDDocument> Pages = splitter.split(pdf1); Iterator<PDDocument> iterator = Pages.listIterator(); PDFMergerUtility PDFmerger = new PDFMergerUtility(); int i = 1; while(iterator.hasNext()) {
if(i==number){
System.out.println("当前插入页码:"+number); pdf2.save(tempPath+"/"+ i +".pdf"); i++; } PDDocument pd = iterator.next(); String tempFile = tempPath+"/"+ i +".pdf"; System.out.println("开始拆分:"+tempFile); pd.save(tempFile); i++; } //2、开始重组 PDFmerger.setDestinationFileName(newfilename); //上面的i最后多加了一次,这里不取等 for(int j=1;j<i;j++){
String tempFile = tempPath+"/"+ j +".pdf"; System.out.println("开始合并:"+tempFile); PDFmerger.addSource(tempFile); } //合并文档 PDFmerger.mergeDocuments(); System.out.println("文档合并完成"); pdf1.close(); pdf2.close(); } 3.测试 //from fhadmin.cn @Test void insertPage() throws Exception {
PdfUtils pdfUtils = new PdfUtils(); String filename1 = "F:\\Users\\admin\\Desktop\\A.pdf"; String filename2 = "F:\\Users\\admin\\Desktop\\B.pdf"; String newfilename = "F:\\Users\\admin\\Desktop\\newA.pdf"; String tempPath = "F:\\Users\\admin\\Desktop\\temp"; int insertNum = 32; pdfUtils.insertPage(filename1,filename2,insertNum,newfilename,tempPath); }
4.使用 Apache PDFBox 操作PDF文件
Apache PDFBox的主要功能如下:
- 从PDF文件中提取Unicode文本。
- 将单个PDF拆分成多个文件或合并多个PDF文件。
- 从PDF表单中提取数据或填写PDF表单。
- 验证PDF文件是否符合 PDF/A-1b 标准。
- 使用标准的Java打印API打印PDF文件。
- 将PDF另存为图像文件,例如PNG或JPEG。
- 从头开始创建PDF,包括嵌入字体和图像。
- 对PDF文件进行数字签名。
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.28</version> </dependency>
创建PDF文档
import java.io.File; import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.font.PDType1Font; public class CreatePDF {
public static void main(String[] args) {
PDDocument document = new PDDocument(); PDPage page = new PDPage(); document.addPage(page); PDType1Font font = PDType1Font.HELVETICA_BOLD; try {
PDPageContentStream contentStream = new PDPageContentStream(document, page); contentStream.beginText(); contentStream.setFont(font, 12); contentStream.newLineAtOffset(100, 700); contentStream.showText("Hello, World!"); contentStream.endText(); contentStream.close(); document.save(new File("one-more.pdf")); document.close(); System.out.println("PDF created successfully."); } catch (IOException e) {
e.printStackTrace(); } } }
import java.io.File; import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.text.PDFTextStripper; public class ReadPDFExample {
public static void main(String[] args) {
// 创建文件对象 File file = new File("one-more.pdf"); try {
// 创建 PDF 文档对象 PDDocument document = PDDocument.load(file); // 创建 PDF 文本剥离器 PDFTextStripper stripper = new PDFTextStripper(); // 获取 PDF 文件的全部内容 String text = stripper.getText(document); // 输出 PDF 文件的全部内容 System.out.println(text); // 关闭 PDF 文档对象 document.close(); } catch (IOException e) {
e.printStackTrace(); } } }
import java.io.File; import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; public class InsertImageInPDF {
public static void main(String[] args) {
try {
// 加载PDF文件 PDDocument document = PDDocument.load(new File("one-more.pdf")); // 获取第一页 PDPage page = document.getPage(0); // 加载图像文件 PDImageXObject image = PDImageXObject.createFromFile("one-more.jpg", document); // 在指定位置插入图像 PDPageContentStream contentStream = new PDPageContentStream(document, page, AppendMode.APPEND, true, true); contentStream.drawImage(image, 200, 500, image.getWidth(), image.getHeight()); // 关闭流 contentStream.close(); // 保存修改后的PDF文件 document.save("one-more-jpg.pdf"); // 关闭文档 document.close(); System.out.println("PDF created successfully."); } catch (IOException e) {
e.printStackTrace(); } } }
读取图片
import java.io.IOException; import java.util.List; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; public class ReadPDFImagesExample {
public static void main(String[] args) {
try {
// 加载PDF文件 PDDocument document = PDDocument.load(new File("one-more-jpg.pdf")); PDPageTree pageTree = document.getPages(); // 遍历每个页面 for (PDPage page : pageTree) {
int pageNum = pageTree.indexOf(page) + 1; int count = 1; System.out.println("Page " + pageNum + ":"); for (COSName xObjectName : page.getResources().getXObjectNames()) {
PDXObject pdxObject = page.getResources().getXObject(xObjectName); if (pdxObject instanceof PDImageXObject) {
PDImageXObject image = (PDImageXObject) pdxObject; System.out.println("Found image with width " + image.getWidth() + "px and height " + image.getHeight() + "px."); String fileName = "one-more-" + pageNum + "-" + count + ".jpg"; ImageIO.write(image.getImage(), "jpg", new File(fileName)); count++; } } } document.close(); } catch (IOException e) {
e.printStackTrace(); } } }
我们使用PDDocument类从指定的PDF文件中加载文档,并遍历每个页面以查找其中的图像。
对于每个页面,我们获取其资源(包括图像)并检查其中是否存在图像。
如果存在,则我们遍历它们,并使用PDImageXObject对象获取它们的属性,例如宽度和高度。
然后,使用ImageIO把图片保存到本地文件系统。
5.PDFBox创建并打印PDF文件, 以及缩放问题的处理.
创建PDF文件
public static byte[] createHelloPDF() {
ByteArrayOutputStream out = new ByteArrayOutputStream(); try {
PDDocument doc = new PDDocument(); PDPage page = new PDPage(); doc.addPage(page); PDFont font = PDType1Font.HELVETICA_BOLD; PDPageContentStream content = new PDPageContentStream(doc, page); content.beginText(); content.setFont(font, 20); content.moveTextPositionByAmount(250, 700); content.drawString("Hello Print!"); content.endText(); content.close(); doc.save(out); doc.close(); } catch (Exception e) {
e.printStackTrace(); } return out.toByteArray(); }
打印文件
// 获取本地创建的空白PDF文件 PDDocument document = PDDocument.load(createHelloPDF()); // 加载成打印文件 PDFPrintable printable = new PDFPrintable(document); PrinterJob job = PrinterJob.getPrinterJob(); job.setPrintable(printable); job.print();
如需要打印自定义纸张, 参加另外一篇博客 使用PDFBox打印自定义纸张的PDF
如果想要读取本地pdf文件, 那就更简单了, 直接
InputStream in = new FileInputStream("d:\\cc.pdf"); PDDocument document = PDDocument.load(in);
public enum Scaling {
// 实际大小 ACTUAL_SIZE, // 缩小 SHRINK_TO_FIT, // 拉伸 STRETCH_TO_FIT, // 适应 SCALE_TO_FIT; private Scaling() {
} }
因此只要在 new PDFPrintable(document), 传入Scaling, 就不会缩放了.
Scaling.ACTUAL_SIZE
6.Java调用PDFBox打印自定义纸张PDF
PDFPrintable printable = new PDFPrintable(document); PrinterJob job = PrinterJob.getPrinterJob(); job.setPrintable(printable);
需要把它放到一个Book中, 再设置即可
Book book = new Book(); book.append(printable, pageFormat); printerJob.setPageable(book); printerJob.print();
设置纸张属性
Paper paper = new Paper(); paper.setSize(width, height); // 设置边距 paper.setImageableArea(marginLeft, marginRight, width - (marginLeft + marginRight), height - (marginTop + marginBottom)); // 自定义页面设置 PageFormat pageFormat = new PageFormat(); // 设置页面横纵向 pageFormat.setOrientation(PageFormat.PORTRAIT); pageFormat.setPaper(paper);
注意: 这边计量单位都是在dpi 72下的尺寸.
如果拿到是mm, 需要转为px. 例如10mm转换
10 * 72 * 10 / 254 = 28px
InputStream in = new FileInputStream("d:\\a3.pdf"); PDDocument document = PDDocument.load(in); PDFPrintable printable = new PDFPrintable(document, Scaling.ACTUAL_SIZE); PrinterJob printerJob = PrinterJob.getPrinterJob(); PaperSize a3 = PaperSize.PAPERSIZE_A3; // A3 纸张在72 dpi下的宽高 841 * 1190 int width = a3.getWidth().toPixI(72); int height = a3.getHeight().toPixI(72); // 10mm边距, 对应 28px int marginLeft = 28; int marginRight = 28; int marginTop = 28; int marginBottom = 28; Paper paper = new Paper(); paper.setSize(width, height); // 设置边距 paper.setImageableArea(marginLeft, marginRight, width - (marginLeft + marginRight), height - (marginTop + marginBottom)); // 自定义页面设置 PageFormat pageFormat = new PageFormat(); // 设置页面横纵向 pageFormat.setOrientation(PageFormat.PORTRAIT); pageFormat.setPaper(paper); Book book = new Book(); book.append(printable, pageFormat); printerJob.setPageable(book); printerJob.print();
word文件格式打印实现
有两种:一种是直接使用jacob进行打印;另外一种则是转换为pdf进行打印
1.Word文件采用jacob插件进行打印实现。
Jacob是一个 Java到微软的com接口的桥梁。使用Jacob允许任何JVM访问com对象,从而使Java应用程序能够调用com对象。如果你要对 Word、Excel 进行处理,Jacob是一个好的选择。
优点:可以很好的处理word文档的相关操作。
缺点:必须手动引入dll文件,暂时未找到方法设置打印相关参数,只能暂时实现静默打印,还需安装office2003以上版本(lz是office365,未激活也可)。
具体实现如下:
①下载jacob.zip ,对应(86/64)的dll文件放在%Java_Home%jre/bin目录下。
下载地址:https://sourceforge.net/projects/jacob-project/
②导入jacob.jar到工程中
<!--添加本地的jacob.jar包--> <dependency> <groupId>com.jacob</groupId> <artifactId>jacob</artifactId> <version>1.19</version> <scope>system</scope> <systemPath>${basedir}/src/main/resources/lib/jacob.jar</systemPath> </dependency>
public static void main(String[] args) {
String filePath = "E:\\a.docx";//文件路径 String printerName = "HP MFP M436 PCL6";//打印机名包含字串 printWord(filePath,printerName); } public static void printWord(String filePath, String printerName){
// 初始化线程 ComThread.InitSTA(); ActiveXComponent word = new ActiveXComponent("Word.Application"); //设置打印机名称 word.setProperty("ActivePrinter", new Variant(printerName)); // 这里Visible是控制文档打开后是可见还是不可见,若是静默打印,那么第三个参数就设为false就好了 Dispatch.put(word, "Visible", new Variant(false)); // 获取文档属性 Dispatch document = word.getProperty("Documents").toDispatch(); // 打开激活文挡 Dispatch doc=Dispatch.call(document, "Open", filePath).toDispatch(); //Dispatch doc = Dispatch.invoke(document, "Open", Dispatch.Method, // new Object[] { filePath }, new int[1]).toDispatch(); try{
Dispatch.callN(doc, "PrintOut"); System.out.println("打印成功!"); }catch (Exception e){
e.printStackTrace(); System.out.println("打印失败"); }finally {
try {
if (doc != null) {
Dispatch.call(doc, "Close", new Variant(0));//word文档关闭 } } catch (Exception e2) {
e2.printStackTrace(); } //退出 word.invoke("Quit", new Variant[0]); //释放资源 ComThread.Release(); ComThread.quitMainSTA(); } }
2.先将word转化为pdf文件,然后打印pdf
具体实现步骤如下:
①因为转化也是使用jacob插件,所以也需要根据第一种方法一样引入jacob相关依赖和文件
②打印pdf文件时,使用的是上面讲述的pdfbox插件,所以也需要引入pdfbox的依赖
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.6</version> </dependency>
首先将word文件转化为pdf文件
//word转化pdf,传入转换前的文件路径(例:"E:\\a.docx")和转换后的文件路径(例:"E:\\a.pdf") public static void wordToPDF(String sFilePath,String toFilePath) {
System.out.println("启动 Word..."); long start = System.currentTimeMillis(); ActiveXComponent app = null; Dispatch doc = null; try {
app = new ActiveXComponent("Word.Application"); app.setProperty("Visible", new Variant(false)); Dispatch docs = app.getProperty("Documents").toDispatch(); doc = Dispatch.call(docs, "Open", sfilePath).toDispatch(); System.out.println("打开文档:" + sfilePath); System.out.println("转换文档到 PDF:" + toFilePath); File tofile = new File(toFilePath); if (tofile.exists()) {
tofile.delete(); } Dispatch.call(doc, "SaveAs", toFilePath, // FileName 17);//17是pdf格式 long end = System.currentTimeMillis(); System.out.println("转换完成..用时:" + (end - start) + "ms."); } catch (Exception e) {
System.out.println("========Error:文档转换失败:" + e.getMessage()); } finally {
Dispatch.call(doc, "Close", false); System.out.println("关闭文档"); if (app != null) app.invoke("Quit", new Variant[]{
}); } // 如果没有这句话,winword.exe进程将不会关闭 ComThread.Release(); }
然后打印pdf文件(这里传入的文件为上面word转化生成的pdf文件)
//这里传入的文件为word转化生成的pdf文件 public static void PDFprint(File file ,String printerName) throws Exception {
PDDocument document = null; try {
document = PDDocument.load(file); PrinterJob printJob = PrinterJob.getPrinterJob(); printJob.setJobName(file.getName()); if (printerName != null) {
// 查找并设置打印机 //获得本台电脑连接的所有打印机 PrintService[] printServices = PrinterJob.lookupPrintServices(); if(printServices == null || printServices.length == 0) {
System.out.print("打印失败,未找到可用打印机,请检查。"); return ; } PrintService printService = null; //匹配指定打印机 for (int i = 0;i < printServices.length; i++) {
System.out.println(printServices[i].getName()); if (printServices[i].getName().contains(printerName)) {
printService = printServices[i]; break; } } if(printService!=null){
printJob.setPrintService(printService); }else{
System.out.print("打印失败,未找到名称为" + printerName + "的打印机,请检查。"); return ; } } //设置纸张及缩放 PDFPrintable pdfPrintable = new PDFPrintable(document, Scaling.ACTUAL_SIZE); //设置多页打印 Book book = new Book(); PageFormat pageFormat = new PageFormat(); //设置打印方向 pageFormat.setOrientation(PageFormat.PORTRAIT);//纵向 pageFormat.setPaper(getPaper());//设置纸张 book.append(pdfPrintable, pageFormat, document.getNumberOfPages()); printJob.setPageable(book); printJob.setCopies(1);//设置打印份数 //添加打印属性 HashPrintRequestAttributeSet pars = new HashPrintRequestAttributeSet(); pars.add(Sides.DUPLEX); //设置单双页 printJob.print(pars); }finally {
if (document != null) {
try {
document.close(); } catch (IOException e) {
e.printStackTrace(); } } } } public static Paper getPaper() {
Paper paper = new Paper(); // 默认为A4纸张,对应像素宽和高分别为 595, 842 int width = 595; int height = 842; // 设置边距,单位是像素,10mm边距,对应 28px int marginLeft = 10; int marginRight = 0; int marginTop = 10; int marginBottom = 0; paper.setSize(width, height); // 下面一行代码,解决了打印内容为空的问题 paper.setImageableArea(marginLeft, marginRight, width - (marginLeft + marginRight), height - (marginTop + marginBottom)); return paper; }
File file=new File(toFilePath); if(file.exists()&&file.isFile()) file.delete();
参考链接
java 打印pdf_java打印pdf文件
java 利用 pdfbox 实现PDF转为图片
java 往 pdf 插入数据 (pdfbox+poi)
使用 Apache PDFBox 操作PDF文件
PDFBox创建并打印PDF文件, 以及缩放问题的处理.
Java调用PDFBox打印自定义纸张PDF
【2023】java打印PDF(不需要调用浏览器直接静默打印)
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/118139.html