本文目录一览:
- 1、别人编写好的jasper,Java调用打印pdf怎么控制其纸张大小
- 2、java调用本地打印机实现打印PDF文件,怎么做
- 3、JAVA打印pdf为什么不显示㮾字?
- 4、java生成pdf
- 5、如何在java中用javascript来打印pdf
别人编写好的jasper,Java调用打印pdf怎么控制其纸张大小
这个从我了解的角度来说只有两个方面:
设计jasper前,设定纸张的大小,选择合适的尺寸 建立jasper。
打印的时候手动选择纸张大小。
java调用本地打印机实现打印PDF文件,怎么做
使用虚拟打印机pdf factory即可实现,而且其他格式文件只要是能够打印,选择这个虚拟打印机,都可以做成PDF文件,很简单实用,一劳永逸。
JAVA打印pdf为什么不显示㮾字?
建议添加spire.pdf.jar为依赖,然后用下面的代码试试
import com.spire.pdf.*;
import java.awt.print.*;
public class Print {
public static void main(String[] args) {
//加载文档
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile("Sample.pdf");
PrinterJob loPrinterJob = PrinterJob.getPrinterJob();
PageFormat loPageFormat = loPrinterJob.defaultPage();
Paper loPaper = loPageFormat.getPaper();
//删除默认页边距 loPaper.setImageableArea(0,0,loPageFormat.getWidth(),loPageFormat.getHeight());
//设置打印份数
loPrinterJob.setCopies(2);
loPageFormat.setPaper(loPaper);
loPrinterJob.setPrintable(pdf,loPageFormat);
try {
loPrinterJob.print();
} catch (PrinterException e) {
e.printStackTrace();
}
}
}
java生成pdf
从JAVA直接读取EXCEL、WORD并生成PDF文件
1。操作EXCEL和WORD文件
使用JAVA从EXCEL、WORD文件中读写数据,可以使用 提供的JAVA API-Java Excel API,这里有其指南 ,可由此下载JAR文件 。
此API提供所有的读、写、修改、建立的功能。对于一般应用足够了。在任何支持JAVA的系统上使用。目前,JExcelApi尚不支持有关chart、graph 或者 macro的信息,但是会拷贝并保留这些信息。只支持PNG图像。
2。生成PDF文件
若从JAVA生成PDF文件,可以使用 提供的应用程序库jPDFWriter。jPDFWriter是一个类库,可以直接从JAVA的应用程序调用以产生PDF文件。其网站的下载文件中包含了说明和例子,有兴趣可以仔细研究。
3。把JExcelAPI和jPDFWriter结合起来,就可以在应用中直接把XLS文件转换成PDF文件。如果再结合Database,就可以直接把有关的报告数据生成XLS文件的同时生成PDF文件。
下边给出了一个例子,是针对XLS,虽然简单,但是完整,以此为基础,可以按照自己的需要展开工作了。对于WORD也是一样,所有不再另给了。
//
//Compile:
//javac -classpath .;jexcelapi/jxl.jar;jPDFWriter/jPDFWriter.jar xlsPrinter.java
//Run:
//java -classpath .;jexcelapi/jxl.jar;jPDFWriter/jPDFWriter.jar xlsPrinter
//
//
import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.util.Vector;
import java.util.Date;
import jxl.*;//JExcelAPI
import com.qoppa.pdfPrinter.PDFPrinterJob;//jPDFWriter
public class xlsPrinter implements Printable
{
private int m_CurrentPage;
private int m_CurrentPageStartRow;
private int m_CurrentPageEndRow;
private final static int DEFAULT_COLUMN_WIDTH = 72;
private final static int CELL_MARGIN_X = 4;
private final static int CELL_MARGIN_Y = 4;
private Vector m_Data;
private int m_ColumnWidths [];
private boolean m_DrawGrid;
/**
* @param printString
*/
public xlsPrinter(Vector data, int [] colWidths, boolean drawGrid)
{
super();
m_Data = data;
m_ColumnWidths = colWidths;
m_DrawGrid = drawGrid;
}
//读取EXCEL数据并存入内存
private static Vector initData ()
{
Vector data = new Vector ();
try{
Workbook workbook = Workbook.getWorkbook(new File("output.xls"));
Sheet sheet = workbook.getSheet(0);
int rows = sheet.getRows();
int cols = sheet.getColumns();
// Initialize data
for (int row = 0; row rows; ++row){
Vector rowData = new Vector ();
for (int col = 0; col cols; ++col){
rowData.addElement (sheet.getCell(col,row).getContents());
}
data.addElement (rowData);
}
workbook.close();
}catch(Exception e){
e.printStackTrace();
}
return data;
}
//主程序
public static void main (String args [])
{
xlsPrinter gridPrinter = new xlsPrinter(initData (), null, true);
PrinterJob printerJob = PDFPrinterJob.getPrinterJob();
printerJob.setPrintable(gridPrinter);
try{
printerJob.print();
}catch (PrinterException pe){
pe.printStackTrace();
}
System.exit(0);
}
//打印接口,由此生成PDF文件,此段代码来源于jPDFWriter的例子
public int print (Graphics g, PageFormat pf, int pageIndex)
{
int lineHeight = g.getFontMetrics().getHeight();
// Reset current pos
int currentRow = 0;
if (pageIndex == 0)
{
// Need to do this in case the instance of this class
// gets used multiple times to print a string
m_CurrentPage = 0;
m_CurrentPageStartRow = 0;
}
// Need to do this because Java PrinterJob can call this
// method multiple times for the same page;
else if (m_CurrentPage == pageIndex)
{
currentRow = m_CurrentPageStartRow;
}
else
{
currentRow = m_CurrentPageEndRow + 1;
m_CurrentPageStartRow = currentRow;
}
// If we're out of lines, tell the PrinterJob we're done
if (currentRow = m_Data.size())
{
return Printable.NO_SUCH_PAGE;
}
// Loop through lines until we fill the page
int currentY = (int)(pf.getImageableY() + lineHeight);
while (currentRow m_Data.size()
currentY + lineHeight pf.getImageableY() + pf.getImageableHeight())
{
// Draw the next line
int currentX = (int)pf.getImageableX();
Vector nextRow = (Vector)m_Data.elementAt (currentRow);
for (int col = 0; col nextRow.size(); ++col)
{
String cellString = (String)nextRow.elementAt (col);
g.drawString (cellString, currentX + CELL_MARGIN_X, currentY + CELL_MARGIN_Y);
int colWidth = DEFAULT_COLUMN_WIDTH;
if (m_ColumnWidths != null m_ColumnWidths.length col)
{
colWidth = m_ColumnWidths [col];
}
// Draw grid if needed
if (m_DrawGrid)
{
g.drawRect (currentX, currentY - (lineHeight / 2), colWidth, lineHeight);
}
// Advance x
currentX += colWidth;
}
// Advance to the next line
++currentRow;
currentY += lineHeight;
}
// Save the ned line and current page
// Again, we have to do this because of multiple calls for the same page.
m_CurrentPageEndRow = currentRow;
m_CurrentPage = pageIndex;
return Printable.PAGE_EXISTS;
}
}
如何在java中用javascript来打印pdf
纯Java的解决方案:
我们首先想到的自然就是JDK1.4提供的JPS(Java Printing Service)啦,不过,这东西虽然说支持PDF的Flavor,但是,不管是个人实验还是网上他人的评论,好像根本就是useless,可能如果说你 的打印机Driver支持PDF的Flavor的话,JPS会检测到你的driver的这个特性,能够成功的打印PDF文档出来,但是,大部分情况下,这 种情形是不成立的,故此JPS死路一条啦!
让我们看看PDF的老家Adobe那里有没有什么法宝,我们发现一个Viewer Bean的组件,说是可以将PDF以Bean组件的方式潜入到Swing中,哇,太爽了,不过慢着,协议上说不提供任何支持,也不保证不出任何问题,管那 么些,试过再说,一实验才知道,靠,Exception频发,而且这个组件较为陈旧,还是扔一边吧!
还有一个PDFBox,Open Source的,不过对中文支持不好,而且好像开发进度也不是很好,没有发布一个正式的版本,基本上不能用于生产环境;
最后,求助于Commercial的产品吧,实验了一下ActiveTree的JPrint,感觉不错,完全可以胜任我们的需求而且恰到好处,不过授权费 很贵,Email问过之后的答复是2000USD的最低购买,呵呵,虽然日本人很有钱,但也心疼这个银子啊,所以最终也得作罢!(ActiveTree的 授权其实挺令我ft的,他其实在2003年的时候是可以免费使用的,但之后就变卦了,呵呵,当时记得我还给提过一些bug之类,算了,人家做出这个东西也 不容易)
其他商业产品也是价格不菲,所以,基本上纯Java的solution到这里就否决了,让我们看Java-Com的解决方案吧!
Java-Com 的解决方案:
在前一条路走不通之后,我痛定思痛,决定转向自己不熟悉的领域,ms的领地,我打算从Java中调用Com组件,由Com组件来帮助我们实现PDF的打印 工作,不够这条路也不是一帆风顺那!
我们知道,Acrobat Reader在发布的时候会随同发布一个支持浏览器的com组件用来manipulate他的这个PDF文档格式,所以,我们想要本地调用这个随同发布的 Com组件来实现PDF打印。虽然Version5,6,7的这个组件格式不一样(5,6是以ocx的格式发布,7是以dll的格式发布),但是,不管那 么些,先从7开始吧!
要调用com,那么我们需要一个从java到com的Bridge,所以,jacob第一个跃入我的脑海,因为之前就用过嘛!但是麻烦来了,我们并不知道 这个com组件提供了那些调用接口啊!哎,没办法,回学校求教熟悉.net的同学,给好不容易弄出几个需要的调用方法(哎,可怜我的周末啊),星期一就回 来用jacob调用啦,可是左试右试就是一直抛异常,我那个气啊!难道是jacob的为问题?!我就又找了jcom和jcom2等类似的产品,但jcom 全是日文文档,没有办法,而jcom2估计也是一个德行(我忘了为什么当初否决了这个),所以就决定试一试商业产品吧!
这方面的商业产品主要有J-Integra,JPanel(好像叫这个名字)以及一个叫JNIWrapper的产品(这个是一个人用用来演示在java中 使用Acrobat5打印PDF的时候提到的)。这些商业产品好的地方就是他可以根据某个你要调用的com组件为你自动生成相应的Proxy对象java 代码,这样你就可以直接调用你熟悉的java代码了。像jacob等开源项目,如果给出一个类似的code generation工具的话,就完全不逊于这些商业产品啦。鉴于商业产品的价格,我最终还是否决了这些(日本人其实也听抠门的)。
这样,Java-com也对这个问题没辙了。
不过,最后在我的解决方案中,我还是使用了Jacob,这是后话,暂且不提...
那我们考虑一下,如果PDF打印不行,打印其他格式行不行?!比如图片,这个JPS可以完全打印,所以,我们找一下有没有将PDF格式转换为其他格式的工 具吧!
PDF格式转换的解决方案:
在这个领域,主要的就是有GhostScript/GView和ImageMagick,前者可以将PDF格式转换为PostScript格式,但是好像 GhostScript也不能用JPS完全打印出来;而后者是一个将PDF转换为Image的API工具,他的Java实现叫JMagick,但他有一个 跟GhostScript同样的问题,就是要转换,就必须在本地安装,然后通过命令行的方式调用,这个显然也不是很好,而且集成性很差,还是作罢!
剩下的一个是命令行调用啦,这是从itext网站找到的,你可以通过在命令行运行AcroRd32 /p /h "path to PDF file"这样的命令来打印你要打印的PDF文件,当然,你可以在PDF文件生成后就将他们依次放入一个批处理文件来执行这些打印命令,但是这个方案唯一 的问题就是,每打印一个文件都会启动一个Acrobat Reader窗口而且必须手动关闭,这现在不能满足目前的系统要求。
好了,所有的方案基本上都罗列完了,也没有找到一个可行的方案:-(
(没有银子嘛,不然Activetree的JPrint不错的说)
这些东西差不多郁闷了我3,4天吧,那几天简直就是bored to death.
不过,在郁闷的这几天的结尾,却有一道灵光闪过我的脑海...
能不能说启动一个打印service,当文档要打印的时候,直接发送给它就行了那?!而恰好我发现一段在网页中加载PDF文档的Javascript代 码,而且完全可以使用js来控制PDF的打印,所以,最终的这个方案就浮出水面了 ...
1-使用jacob启动一个IE进程,并隐藏IE窗口;
if(ieAutomation == null)
ieAutomation = new ActiveXComponent("InternetExplorer.Application");
ieAutomation.setProperty("Visible",new Variant(false));
2-PDF前端在生成PDF文件之后发送生成后的文件到JacobPDFPrinter,JacobPDFPrinter根据出入的PDF文件的全路径使 用Velocity模板引擎动态生成一个包含使用Javascript代码实现的PDF打印逻辑的HTML文档(当然,使用Velocity生成文档这部 分逻辑我们单独抽出到VeloIEPrinterGenerator类中);
3-在HTML生成之后,在JacobPDFPrinter中就可以使用jacob调用IE的Navigate2,将IE重定向到刚才生成的这个HTML 文件啦,这样,IE就会在后台调用JS代码将PDF打印到默认打印机;
4-打印成功之后,清除临时动态生成的HTML文件;
5-当主程序退出之前,Quit后台IE进程。
以上就是我能给出的一个solution,并不完美,但it works.
需要注意的几个问题是:
(1)需要设置IE的一个高级选项,运行本地脚本运行;
(2)因为Java和Com线程模型的不一致,导致在最终Quit后台IE进程的时候会抛出Com调用异常,因为对于Win平台API以及相关编程模型不 是很熟悉,所以,这个问题需要求助于别人帮忙解决;
(3)IE在执行JS打印PDF的时候,同样会后台启动Acrobat的一个进程,而这个进程我们程序中无法控制其生命周期,所以,主程序退出后,我们没 有办法同时kill这个进程,好在不管我们运行多少次,这个进程在后台只有一个,所以,性能负担不是很大;
转载