-
Java 实现批量静默打印PDF文件
2013-05-24 10:51:08经过几番折腾,我对批量打印PDF文件有了比较深入的了解。起初想通过使用JAVA 代码操纵PDF文件打印,但最终还是失败了,没能达到最终的效果。后来了解到可以用JAVA调用第三方软件的形式进行间接打印,这其中我试过了...对于java的打印功能我本人从来没有使用过,不过也看过网上的一些文章,都说使用起来不方便且对各种文档类型的支持不是很好。经过几番折腾,我对批量打印PDF文件有了比较深入的了解。起初想通过使用JAVA 代码操纵PDF文件打印,但最终还是失败了,没能达到最终的效果。后来了解到可以用JAVA调用第三方软件的形式进行间接打印,这其中我试过了好几款软件也都没达到要求,像福昕、gsview、adobe什么的。有的不能在批量打印时切换打印机,有的对PDF文件内嵌的中文字体支持不好,最终全部放弃。
后来发现了一款国外软件叫pdfPrint的软件,大家可以去官网找一下,该公司有很多有关PDF 文件操作的软件,很好用,但都是收费使用。下面说说pdfPrint的使用方法吧。
该软件是通过命令行的方式打印PDF文件的,打印的方式都是通过命令行参数的方式进行配置的,参数有很多,相当的方便。包括边界、份数、起始页、缩放、位置方向等应有尽有。基本可以满足大部分对于PDF文件的打印需求。当然我的打印问题就是有它完美解决的。下面就我在使用过程中遇到的难点重点解释一下:
Usage: pdfprint.exe [options] [Options] <PDF Files>
-firstpage <int> : first page to print, from 1 to max page
-lastpage <int> : last page to print, from 1 to max page
-prompt : prompt the user with the print dialog so they can change printer settings and/or select pages manually
-printer <string> : printer name to print指定打印机,打印机名称中如果有空格,需用""引起来。
-savedevmode <string> : prompt the user with print dialog and save the printer settings into a disk file
-loaddevmode <string> : restore printer settings which saved by -savedevmode parameter
-promptdevmode : prompt the user with print dialog and print the printer settings to screen
-devmode <string> : restore printer settings which outputed by -promptdevmode parameter
-copies <int> : set number of copies to print
-setcopyto : set '-copies' value to printer instead of print it several times
-paper <string> : paper size to printer
pdf : retrieve paper size from PDF file
number : standard paper size
others : user defined paper size打印机纸张类型,一般A4 = 9,A3=8
-scalex <int> : X axis scale factors, default is 100
100 : do not scale PDF page
0 : scale the width of PDF page to fit the printer's paper size
-1 : keep the minimum constant scaling in both paper width and height
-scaley <int> : Y axis scale factors, default is 100
100 : do not scale PDF page
0 : scale the height of PDF page to fit the printer's paper size
-1 : keep the minimum constant scaling in both paper width and height
-pdforient <int> : select the orientation of the show PDF page,
0 : upright, default
1 : upside down
2 : left side down
3 : right side down
4 : auto detect orientation for PDF pages
-orient <int> : select the orientation of the printer paper,
1 is portrait (default) and 2 is landscape纸张打印方向,有些打印机不能自动判别文档方向,需加此参数,否则文档打印不完整。
-duplex <int> : select duplex or double-sided printing for printers capable of duplex printing,
1 : simplex
2 : horizontal
3 : vertical
-color <int> : specify color or monochrome to printer,
1 : monochrome
2 : color
-xres <int> : specify the printer x-resolution,
-4 : high
-3 : medium
-2 : low
-1 : draft
number: the number of dots per inch (DPI) and is therefore device dependent
-yres <int> : specify the printer y-resolution
-xoffset <int> : specify a page offset in the horizontal axis
-yoffset <int> : specify a page offset in the vertical axis
-collate <int> : specify whether collation should be used when
printing multiple copies, 0 is disable and 1 is enable
-scale <int> : specify the factor by which the printed output
is to be scaled, The apparent page size is scaled from the physical page
size by a factor of scale/100.
-shell : Call default PDF viewer to print PDF file
-shell2 : Call default PDF viewer to print PDF file
-shelltime <int> : set timeout for shell printing,in milliseconds
-raster : render PDF page to image before printing
-raster2 : render PDF page to image before printing
-rasterbitcount <int> : set bitcount for raster image, e.g., 1, 8, 24
-rasterbwtext : disable halftone for color text, for -raster2 only
-preproc : process PDF file before printing, useful for some damaged PDF files
-printtofile <string> : save print spooling data to a disk file
-mergeprintjobs : combine all print jobs into one print job
-listprinter : list printers in system
-listbins : list bins/trays of a printer
-listjobs : list print jobs in printer's queue
-listall : list printers, ports, monitors etc.
-chgbin <int> : change bin/tray for printer by number
-papersource <string> : change bin/tray for printer by name打印机纸盒
-winfont : use Windows fonts to instead of embedded fonts
-winfont2 : force to use Windows fonts to instead of all embedded fonts
-useembedfont : use embedded fonts from PDF file
-useunicode <int> : enable or disable unicode conversion for PDF printing
-antifonts : enable anti-aliased font bitmaps for emulated fonts
-nochgprinter : don't change default printer during printing该参数相当重要,如果不加该参数的话,在打印的时候不能正常随意切换打印机,系统总是将所有打印任务发送到第一个任务指定的打印机
-restoreprinter : restore original settings to printer after printing
-printermargins : reduce to printer margins when printing打印边框,有些PDF文件边框比较窄,不使用此参数可能导致边框打印不完全。
-checkjobstatus : check status for print jobs
-checkjobtime <int> : delay some time before check status for print jobs, in millisecond
-nodelfailjobs : don't delete failed print jobs
-movetotop : move print area to top if printer paper not same as PDF paper, default is 'center'
-openpassword <string> : set open password to PDF file
-ispasswordprotected : check if a PDF file protected by 'open password' or not
-getpagecount : read page count from input PDF file
-jobusername <string> : specify the name of the user who owns the print job
-jobdocname <string> : specify document name of print job
-ownerservicename <string> : specify the name of OwnerService on Windows Server 2008
-deleteownerservice <string> : remove the OwnerService from Windows
-silent : print PDF files silently对于中文特别说明的地方需特别注意,其它的参数使用比较少。
言归正传,JAVA程序打印PDF在上述的基础之上,通过JAVA 语言操作命令行的方式即可轻松实现。
语法为:Runtime.getRuntime().exec("");而批量打印的实现即是隐藏在此处。
同时官网下载的版本为试用版本,打印时有水印,可以通过脱壳软件对.exe文件进行脱壳后,通过查找的方式将代码中的水印文字替换成"",再
进行重新打包即可,过程不是很复杂,本人成功操作过。
另该软件网址为:www.verypdf.com
-
JAVA 实现批量PDF 打印,线程池多线程执行(附完整代码)
2020-06-09 10:34:20还是说到前面那篇使用 JAVA 使用 pdfbox实现打印 PDF 文件,使用 pdfbox调用 pdf是可以进行打印的,我在本地电脑进行打印的时候是对的,那是因为,我本地电脑是连接过打印机的,所以当然是可以进行打印文件的,那...还是说到前面那篇使用 JAVA 使用 pdfbox实现打印 PDF 文件,使用 pdfbox调用 pdf是可以进行打印的,我在本地电脑进行打印的时候是对的,那是因为,我本地电脑是连接过打印机的,所以当然是可以进行打印文件的,那如果部署到服务器上面,老是会报,未连接打印机的问题,然后我查询了很多的资料,都没有找到答案,有的说服务器上面要安装打印机连接工具才可以,那肯定是不可以的,因为我们做的功能不能说我们知道客户的打印是叫啥然后去连接,既然服务端无法识别,那我还是只能用客户端去实现了,这里我想到的方法就是,批量生成多个pdf文件,然后把这些文件都放入到一个文件中,然后在页面中预览,在进行打印这样就可以实现了,因为我还没找到服务端去进行打印的例子如果有,请告诉我一下谢谢,我也可以去学习下,接下来就去看看代码吧:
long startTime = System.currentTimeMillis(); //获取开始时间 ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2,10,1L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(3), Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardOldestPolicy());//定义线程池 List<Future<String> > arrayList = new ArrayList<>(); //用于接受线程执行的返回值 //生成pdf 签章: String[] split = batchId.split(","); for(int i=0;i<split.length;i++){ arrayList.add(threadPool.submit(new CarPdfCallable(orderService, propertiesUtil, split[i], templateId, zjl, cw, hg, zb))); //这里去执行生成pdf 签章的方法 } CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList(); //使用并发list去接受值,这里我怕值会乱所以用了并发的list String contractId = StringUtils.randomUUID();//生成新的pdf文件的名字 for(int i=0;i<arrayList.size();i++){ if(StringUtils.isNotEmpty(arrayList.get(i).get())){ copyOnWriteArrayList.add(propertiesUtil.getString("fadada.temp.path")+arrayList.get(i).get());//获取放回值 } } String[] objects=copyOnWriteArrayList.toArray(new String[copyOnWriteArrayList.size()]); //转换成数组 String filePatch = contractId + ".pdf"; boolean b = mergePdfFiles(objects, propertiesUtil.getString("fadada.temp.path")+"pdf\\" +filePatch); //多个pdf写入到一个新的pdf文件中 if(b){ model.addAttribute("filePatch",filePatch); } long endTime = System.currentTimeMillis(); //获取结束时间 System.err.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间 计算程序运行的时间
这里其实是有一个问题,大家有没有注意到一点,为啥获取值要这么麻烦,为啥不在第一个循环中调用?其实这里是个坑,之前我的写法是这样的
for(int i=0;i<split.length;i++){ Future<String> arrayList= threadPool.submit(new CarPdfCallable(orderService, propertiesUtil, split[i], templateId, zjl, cw, hg, zb)) arrayList.get(); }
这里看似是没有问题,但是运行后我发现很慢,并且页面直接说504,浏览器请求超时,然后就在程序还是一直在运行,并且是一个一个生成文件,这是为什么?
不是多线程执行程序,后来查询资料才发现 arrayList.get();这个方法是线程阻塞的,如果直接写在里面就变的和一个一个执行的一样的了,所以这个方法不能这样去写。
CarPdfCallable/** * @author qrn * @version 1.0 * @date 2020/6/4 16:29 */ public class CarPdfCallable implements Callable<String> { IOrderService orderService; PropertiesUtil propertiesUtil = PropertiesUtil.create("common.properties"); /** * 批次Id */ private String batchId; /** * 模板Id */ private String templateId; private String zjl; private String cw; private String hg; private String zb; public CarPdfCallable(IOrderService orderService, PropertiesUtil propertiesUtil, String batchId, String templateId, String zjl, String cw, String hg, String zb) { this.orderService = orderService; this.propertiesUtil = propertiesUtil; this.batchId = batchId; this.templateId = templateId; this.zjl = zjl; this.cw = cw; this.hg = hg; this.zb = zb; } @Override public String call() throws Exception { String file = ""; String filePatch = orderService.signOrderPayment(batchId, templateId, "","",zjl,cw,hg,zb); if(StringUtils.isNotEmpty(filePatch)){ // copyOnWriteArrayList.add(propertiesUtil.getString("fadada.temp.path")+filePatch); file = filePatch; } return file; } }
这里实现了Callable,这个是多线程执行时,异步返回返回值。里面只有一个方法就是生成pdf文件,然后返回文件名字,用于写入到一个新的文件中
mergePdfFiles方法:
public static boolean mergePdfFiles(String[] files, String newfile) { boolean retValue = false; Document document = null; try { File file = new File(newfile); if(!file.exists()){ file.createNewFile(); } document = new Document(new PdfReader(files[0]).getPageSize(1)); PdfCopy copy = new PdfCopy(document, new FileOutputStream(file.getPath())); document.open(); for (int i = 0; i < files.length; i++) { PdfReader reader = new PdfReader(files[i]); int n = reader.getNumberOfPages(); for (int j = 1; j <= n; j++) { document.newPage(); PdfImportedPage page = copy.getImportedPage(reader, j); copy.addPage(page); } } retValue = true; } catch (Exception e) { System.out.println(e); } finally { System.out.println("执行结束"); document.close(); } return retValue; }
这样子在不出问题的情况下,我把所有pdf文件写入到一个pdf文件中,然后在页面中展示,直接用pdf自带的浏览器打印就很好的实现这个问题。好了这个问题记录下来,希望对有需要的朋友有帮助。
-
java 打印tiff及批量打印图片
2012-04-19 16:39:06刚开始只能做到把tiff图片分解成功,并单页打印,没办法实现多页连续打印,由于我对java Printable 这个类不是很了解,所以在哪个循环的地方控制不好,无法实现多页连续打印。但为了完成任务,我想办法把tiff图片...前几天老大让我做一个java print tiff格式图片的程序,而我对这个一无所知,幸好老大给我了些资料。刚开始只能做到把tiff图片分解成功,并单页打印,没办法实现多页连续打印,由于我对java Printable 这个类不是很了解,所以在哪个循环的地方控制不好,无法实现多页连续打印。但为了完成任务,我想办法把tiff图片文件转化成为了pdf文件,但是pdf文件在java中也不容易打印,所以我只好调用Adobe Reader 的打印程序打印,但是这个不是很好,需要客户装Adobe Reader 才行。后来经过老大稍微修改,实现了多页打印。后来发现其实我对哪个Printtable 里面的哪个pageIndex参数没有理解。
程序中需要的jar文件:jai_codec.jar;jai_core.jar;iText-2.1.3.jar(自己网上下吧,我也是自己找的,网址没有记下来);需要安装 jai_imageio插件(https://jai-imageio.dev.java.net/binary-builds.html);
java 直接连续打印tiff 程序:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.renderable.ParameterBlock;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.util.Vector;
import javax.imageio.ImageReader;
import javax.imageio.spi.IIORegistry;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.ImageInputStream;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.RenderedOp;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.SeekableStream;
import com.sun.media.jai.codec.TIFFDecodeParam;
import com.sun.media.jai.codec.TIFFDirectory;
public class PrintTiff {
private BufferedImage[] bi = null;
private File tiffFile = null;
private int pages = 0;
public static void main(String[] args) throws Exception {
PrintTiff pt = new PrintTiff("3699_001.tif");//自己的tiff文件,我是把它放在程序的同一个目录下面
pt.print();
}
public PrintTiff(String file) {
tiffFile = new File(file);
init();
}
private void init() {
try {
ImageReader tiffReader;
ImageInputStream input;
input = new FileImageInputStream(tiffFile);
//以下为读取tiff文件
IIORegistry iioreg = IIORegistry.getDefaultInstance();
iioreg.registerApplicationClasspathSpis();
ImageReaderSpi irs = new com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi();
tiffReader = irs.createReaderInstance();
tiffReader.setInput(input);
//获取tiff文件的页数
pages = tiffReader.getNumImages(true);
if (pages > 0) {
bi = new BufferedImage[pages];
for (int i = 0; i < pages; i++) {
//把每一页放入 BufferedImage[]数组
bi[i] = tiffReader.read(i, null);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void print() throws PrinterException {
PrinterJob job = PrinterJob.getPrinterJob();
PageFormat format = job.defaultPage();
double inch = 72;
Paper paper = format.getPaper();
paper.setImageableArea(inch, inch, paper.getWidth() - 2 * inch, paper
.getHeight()
- 2 * inch);
format.setPaper(paper);
MyPrintable p = new MyPrintable();
job.setPrintable(p);
if (job.printDialog()) {
job.print();
}
}
private class MyPrintable implements Printable {
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException {
if (pageIndex == pages) {
return NO_SUCH_PAGE;
}
graphics.translate((int) pageFormat.getImageableX(),
(int) pageFormat.getImageableY());
//打印每一页。关键在于bi[pageIndex],我当时对pageIndex不明白,不知道它是怎么循环取值的,所以开始的想法//是把bi[i]整合到一个文件里面去再打印。
graphics.drawImage(bi[pageIndex], 0, 0, 450, 650, null);
return PAGE_EXISTS;
}
}
}
下面是我做的把tiff转化为pdf后调用Adobe Reader 打印程序打印的。虽然没多大作用,但是我发现转化后的打印格式似乎比直接打印tiff好看些,而且质量也不差。就当作学习吧。
package example;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.ServiceUI;
import javax.print.SimpleDoc;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import com.lowagie.text.Document;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.SeekableStream;
import com.sun.media.jai.codec.TIFFDirectory;
import com.sun.media.jai.codecimpl.TIFFImageDecoder;
public class TiffToPDF {
Document document;
PdfContentByte cb;
public TiffToPDF(String filename, String[] strImages) throws Exception {
document = new Document();
FileOutputStream rech = new FileOutputStream(filename);
PdfWriter writer = PdfWriter.getInstance(document, rech);
document.open();
cb = writer.getDirectContent();
for (int i = 0; i < strImages.length; ++i) {
addImage(strImages[i]);
}
document.close();
}
public void addImage(String strImageName) throws Exception {
System.out.println(strImageName);
File file = new File(strImageName);
SeekableStream stream = new FileSeekableStream(strImageName);
TIFFDirectory dir = new TIFFDirectory(stream, 0);
String[] names = ImageCodec.getDecoderNames(stream);
ImageDecoder dec = ImageCodec
.createImageDecoder(names[0], stream, null);
int total = dec.getNumPages();
for (int k = 0; k < total; ++k) {
RenderedImage ri = dec.decodeAsRenderedImage(k);
Raster ra = ri.getData();
BufferedImage bi = new BufferedImage(ri.getColorModel(), Raster
.createWritableRaster(ri.getSampleModel(), ra
.getDataBuffer(), null), false, new Hashtable());
Image img = Image.getInstance(bi, null, true);
long h = 0;
long w = 0;
long IFDOffset = dir.getIFDOffset();
while (IFDOffset != 0L) {
dir = new TIFFDirectory(stream, IFDOffset, 0);
IFDOffset = dir.getNextIFDOffset();
h = dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_LENGTH);
w = dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_WIDTH);
}
float percent = 100;
int pos = 0;
if (w > 895)
percent = ((595 + 18) * 100 / w);
if (h > 842)
pos = (int) (842 - h * percent / 100);
else
pos = (int) (842 - h);
System.out.println(percent);
System.out.println(pos);
img.scalePercent(percent);
img.setAbsolutePosition(0, pos);
System.out.println("Image: " + k);
cb.addImage(img);
document.newPage();
}
stream.close();
// file.delete();
}
public static void print() {
/****
这一段本来是想调用java自带的打印程序打印pdf的,但是行不通,问朋友都说用其他的插件打,
我一个同事以前自己用vb做了个打印pdf的exe文件,但是传进去的是他自己的特定参数,我不方便调用。
在佩服他能用vb做一个自己需要的exe文件
************/
// File file = new File("test.txt");// 获取选择的文件
// // 构建打印请求属性集
// PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
// // 设置打印格式,因为未确定文件类型,这里选择AUTOSENSE
// DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF;
// // 查找所有的可用打印服务
// PrintService printService[] = PrintServiceLookup.lookupPrintServices(
// flavor, pras);
// // 定位默认的打印服务
// PrintService defaultService = PrintServiceLookup
// .lookupDefaultPrintService();
// // 显示打印对话框
// PrintService service = ServiceUI.printDialog(null, 200, 200,
// printService, defaultService, flavor, pras);
// if (service != null) {
// try {
// DocPrintJob job = service.createPrintJob();// 创建打印作业
// FileInputStream fis = new FileInputStream(file);// 构造待打印的文件流
// DocAttributeSet das = new HashDocAttributeSet();
// Doc doc = new SimpleDoc(fis, flavor, das);// 建立打印文件格式
// job.print(doc, pras);// 进行文件的打印
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
/
//以下是打印
String sysName = System.getProperty("os.name");
String exeName = "start";
if (sysName.startsWith("Windows")) {
if (exeName.equals("start")) {
Runtime rn = Runtime.getRuntime();
try {
String cmd[] = {
"D:\\Program Files\\Adobe\\Reader 8.0\\Reader\\AcroRd32.exe",
"temp.pdf" };
Process p = Runtime.getRuntime().exec(
"cmd.exe /C start acrord32.exe /p" + "./temp.pdf");
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
exeName = "stop";
} catch (IOException e) {
e.printStackTrace();
}
} else if (exeName.equals("stop")) {
try {
Runtime.getRuntime().exec(
"cmd.exe /c taskkill /im acrord32.exe /f");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
try {
String[] temp = { "3699_001.tif" };
TiffToPDF build = new TiffToPDF("temp.pdf", temp);
print();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这个打印在网上的资料似乎很少,所以写出来希望有帮助。批量打印图片应该根据打印tiff思想可以稍微修改一下,就是从一个目录里面读取所以图片就行,我还没写 呵呵,改天试一下,弄好再传上来。 -
有没有方法实现条形码批量打印
2015-07-02 02:50:19目前有一台斑马条码打印机,usb接口链接,Java已经实现批量生成条形码图片文件,但是用什么方法来实现批量打印呢,在线等解答,谢谢各位 -
JAVA 使用 pdfbox实现打印 PDF 文件 (横版,竖版)
2020-06-03 16:01:57最近又收一个任务,说是要弄批量打印,这个打印的需求是真的一直在表,之前是说只要打印,然后我想的第一种方法是 使用 浏览器去调用打印也就是 Window print() 去调用打印,这里不会的可以看看这一篇文章,还附有...最近又收一个任务,说是要弄批量打印,这个打印的需求是真的一直在表,之前是说只要打印,然后我想的第一种方法是 使用 浏览器去调用打印也就是 Window print() 去调用打印,这里不会的可以看看这一篇文章,还附有表格的前端代码
Window print打印
然后需求是 希望能在表格中进行签章,这里还要用到外部的接口给用户进行签章,这里的需求那么就不能使用 Window print() 方法去实现,因为不会在是一个html表格了,而是一个pdf文件,这样子其实也没什么,我们只要把文件放也页面中显示那么也还是调用起浏览器的打印按钮,也可以实现打印的功能:
html:<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>打印</title> <meta name="decorator" content="form"/> <script type="text/javascript"> // 后端传过来的pdf文件地址 ,这样子我们就可以直接在页面中看到pdf文件,那么也可以调用浏览器的打印了。 $(function(){ var filePatch = "${filePatch}"; window.location.href = "http://xxxxx/temp/"+filePatch; }); </script> </head> <body> </body> </html>
但是这里有一个问题,就是说不能设置打印的布局,也就是说默认是竖向打印
那如果我们需要横向打印咋办,这里说实话找了很久还是没找到,最后我们想的办法就是 把pdf文件格式做成横版的,这样打印的不就横板的了吗。使用这个方法我的问题解决了,打印机打印是横向的。
以为这样就结束了,不不不没有,突然又有问题过了说,我们能不能进行批量打印,不需要一个一个点击打印,这个需求说真的,是真的多,为啥不早点说,好吧,这样的需求那么上面的方案就全部不能用了,我们总不能生成很多pdf文件然后让用户页面上面一个一个点击打印吧,还不如用程序直接给他打印。其实也很简单,就是用java实现打印机打印不就可以了。这里我使用的pdfbox工具,不得不说,这也太厉害了,写出这个的人一定是一个巨佬,膜拜一下,我们来看看官方文档:
https://pdfbox.apache.org/
https://iowiki.com/pdfbox/pdfbox_quick_guide.html我这里只需要打印功能,其实不难看出,打印功能是jdk自带的,感兴趣的朋友可以去看看源码,java.awt.print.PrinterJob; 这个类 print 方法就是打印的方法了
话不多说,直接看代码吧:/** * 打印 * @param filePath * @return */ public static String demo(String filePath) { PrintService[] printServices = PrinterJob.lookupPrintServices(); if (printServices == null || printServices.length == 0) { return "打印失败,未找到可用打印机,请检查。"; } try { File file = new File(filePath); PDDocument document = PDDocument.load(file); // 加载成打印文件 PDFPrintable printable = new PDFPrintable(document, Scaling.SCALE_TO_FIT); PrinterJob job = PrinterJob.getPrinterJob(); job.setPrintable(printable); job.defaultPage(); job.print(); return "打印成功"; } catch (InvalidPasswordException e) { System.err.println("打印异常:文档初始化密码失败!"); e.printStackTrace(); } catch (IOException e) { System.err.println("打印异常"); e.printStackTrace(); } catch (PrinterException e) { System.err.println("未正常连接打印机"); e.printStackTrace(); } return "打印失败"; }
这个代码就是主要实现打印的核心代码了,前面还校验了电脑是否连接了打印机,没有连接打印机当然不能打印了,也打印不了,然后就进入下面进行打印,这样子是很简单,但是这代码,打印出来的文件默认是竖版的,我找了很久都没有找到去哪里设置横版的属性,不过,还是被我找到了,很简单就是设置了一下属性,看代码:
/** * 打印 横版 * @param filePath * @return */ public static String demo2(String filePath) { PrintService[] printServices = PrinterJob.lookupPrintServices(); if (printServices == null || printServices.length == 0) { return "打印失败,未找到可用打印机,请检查。"; } try { File file = new File(filePath); PDDocument document = PDDocument.load(file); // 加载成打印文件 PDFPrintable printable = new PDFPrintable(document, Scaling.SCALE_TO_FIT); Book book = new Book(); PageFormat pageFormat = new PageFormat(); //设置打印方向 PORTRAIT 竖向 REVERSE_LANDSCAPE 横向 pageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE); // 设置纸张 book.append(printable, pageFormat, document.getNumberOfPages()); PrinterJob job = PrinterJob.getPrinterJob(); job.setPageable(book); // job.setPrintable(printable); job.defaultPage(); job.print(); return "打印成功"; } catch (InvalidPasswordException e) { System.err.println("打印异常:文档初始化密码失败!"); e.printStackTrace(); } catch (IOException e) { System.err.println("打印异常"); e.printStackTrace(); } catch (PrinterException e) { System.err.println("未正常连接打印机"); e.printStackTrace(); } return "打印失败"; }
好了,其他一下细节上面的设置,就好靠你们自己去寻找了,有问题下方评论,有时间会回复,有问题大家可以一起讨论,谢谢
-
java 浏览器打印控件_很多浏览器都禁用 java 打印了,java 项目还有哪些打印方式...
2021-02-26 19:11:08常见的打印方式除 java 打印外还有 pdf...下面举例说明1.Pdf 打印环境要求:浏览器安装 pdf 插件,如 adobeReader X优点:从服务器端下载 pdf 文件流,可以实现精准套打、批量打印等。缺点: 需要下载 adobe 插件2.... -
很多浏览器都禁用 java 打印了,java 项目还有哪些打印方式
2020-06-29 08:09:46常见的打印方式除 java 打印外还有 ...优点:从服务器端下载 pdf 文件流,可以实现精准套打、批量打印等。 缺点: 需要下载 adobe 插件 2.Flash 打印 环境要求:浏览器支持 flash 插件 优点: 打印模式为矢量打印. -
java调用帆软cpt文件_JS调用finereport打印方法
2021-03-03 12:21:061.描述在进行报表集成时,常常需要通过js来调用FR的打印事件,如实例:不查看报表直接打印、自定打印按钮、批量打印等等。FR实现了Flash、Pdf、Applet三种客户端打印js方法,doURLFlashPrint、doURLPDFPrint、... -
Java:基于ORM技术的配置文件持久化实现
2014-04-20 15:18:24概述:本文介绍了利用ORM(Object/Relational Mapper,对象关系映射)技术和Java中的注解、反射等特性实现配置文件的持久化,实现了实体类和配置文件的映射、配置文件的自动加载和自动保存。 这个想法来源于... -
jxl实用例子及实现批量转移数据的想法
2009-03-18 15:45:00作为办公文档,势必要涉及到的电子文档的交换,Excel是一种在企业中非常通用的文件格式,打印和管理也比较方便。在一个Java应用中,将一部分数据生成Excel格式,是与其他系统无缝连接的重要手段。 在开源世界中,有... -
JAVA上百实例源码以及开源项目
2016-01-03 17:37:40Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个... -
JAVA上百实例源码以及开源项目源代码
2018-12-11 17:07:42Java实现的FTP连接与数据浏览程序 1个目标文件 摘要:Java源码,网络相关,FTP Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。 部分源代码摘录: ftpClient = new FtpClient(); //实例化FtpClient对象 ... -
疯狂JAVA讲义
2014-10-17 13:35:01学生提问:当我们使用编译C程序时,不仅需要指定存放目标文件的位置,也需要指定目标文件的文件名,这里使用javac编译Java程序时怎么不需要指定目标文件的文件名呢? 13 1.5.3 运行Java程序 14 1.5.4 根据... -
Java与报表知识概括
2020-12-31 11:27:19通俗的讲,poi就是批量的操作文件或数据的导入以及导出。 为什么要用POI? 举例: ①在开发过程中常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统、银行系统)。或者是:我们已经习惯用Excel打印。... -
《Java Web开发实战1200例(第I卷)》(清华出版.卢瀚.王春斌).part2 高清完整PDF版
2016-06-13 12:06:47实例326 使用commons-fileUpload实现文件批量上传 第3篇 图像与多媒体篇 第13章 图像生成 13.1 绘制图形和文本 实例327 绘制直线 实例328 绘制矩形 实例329 绘制正方形 实例330 绘制椭圆 实例331... -
Java开发实战1200例(第2卷)(完整版).(清华出版.李钟尉.陈丹丹).part1
2016-06-12 23:30:05实例114 批量打印条形码 181 实例115 相册特效打印程序 183 实例116 镜面效果文本打印 186 实例117 透明的打印预览对话框 187 第6章 管理图像文件 189 6.1 图像的修改与保存 190 实例118 保存图片文件 190 实例119 ... -
ASP200问.EXE
2010-05-20 13:25:08120.用ASP实现远程批量文件改名 121.实现无组件文件上传 122.利用组件实现复杂上传功能 123.利用Stream读取显示文件 123.利用Stream上传文件 124.计算下载一个文件需要多长时间 第8章 表单与页面显示 127.如何处理... -
getFromAssets : 获取asset文件下的资源文件信息 设置Badge数字角标 -> BadgeUtils.java 回到目录 setBadgeCount : 设置Badge 目前支持Launcher:MIUI、Sony、Samsung、LG、HTC、...
-
Apache Flink是一个面向分布式数据流处理和批量数据处理的开源计算平台,提供支持流处理和批处理两种类型应用的功能。文章会对Flink中基本API如:DataSet、DataStream、Table、Sql和常用特性如:Time&Window、...
-
vc代码合集
2012-06-11 11:34:522012-06-11 09:50 3,412,722 内部文件非内部程序员禁止访问谢谢1234567890123456789能够实现文件的多选,统一上传,从而实现文件的批量上传Flex多文件上传源码VS2005.rar 2012-06-11 10:08 1,481,225 几个C语言小... -
EmEditor V12+注册码
2013-01-22 11:53:13Windows系统自带的“记事本”的查找替换功能很弱,但EmEditor弥补了这一点,它支持的查找替换规则更加详细实用,对查找出的结果可以突出显示,并可以批量查找替换未打开的TXT、HTML、DOC等格式的文件中的内容:选择... -
部分vc源代码合集1.rar
2012-06-11 11:20:012012-06-11 09:50 3,412,722 内部文件非内部程序员禁止访问谢谢1234567890123456789能够实现文件的多选,统一上传,从而实现文件的批量上传Flex多文件上传源码VS2005.rar 2012-06-11 10:08 1,481,225 几个C语言小... -
uniout:打印可读的字符,而不是转义的字符串。 xpinyin:一个用于把汉字转换为拼音的库。 pyfiglet:figlet 的 Python 实现。 flashtext:一个高效的文本查找替换库。 textdistance:支持 30 多种算法来计算...
-
易语言程序免安装版下载
2011-04-07 09:28:50为实现静态编译,易语言编译器、核心支持库、集成开发环境(IDE)等均有重大更新,支持库开发架框有扩展性调整,绝大多数官方支持库都已针对静态编译完成自身改造并提供静态库。 目前绝大多数官方支持库均已支持... -
若干源程序资料12.rar
2012-06-11 22:11:262012-06-11 21:43 1,480,155 Direct3D加载3d文件.rar 2012-06-11 21:29 22,102 DSP编程一周通.rar 2012-06-11 21:04 837,926 fatfs-0.08b.zip 2012-06-11 21:11 48,640 FFT算法.doc 2012-06-11 21:28 10,891,658 GPS...