我正在用 Java 开发一个身份证管理应用程序,它将取代几十年前过时的大型机系统。所需的功能包括在由点阵打印机馈送的卡片上打印个人数据。每张卡片的页面尺寸为 3.5" 高 × 8.5" 宽。
为了说明我的问题,下面的程序创建了一个包含一些数据的两页示例打印输出。
- 我使用 PDFCreator 作为打印机,但我发现它的行为与点阵打印机完全相同,因此任何阅读这篇文章的人都可以对其进行测试。
- 页面大小和布局是正确的,但页面旋转了 90°,以便垂直“进纸”。
- 在激光打印机上,这不会造成任何问题,因为人们也会垂直进纸(例如 Com-10 信封)。但这对于点阵打印机上的折叠纸是不可接受的。
- 顺便说一句,这张折叠纸有一个预印模板,所以无论如何都不能旋转。
- 无论我使用任何页面方向选项(即在 PrintRequestAttributeSet 中放置 OrientationRequested 参数),似乎都不可能使打印输出不旋转,即将 3.5" × 8.5" 页面保持其原始水平方向。
- 运行下面的程序时,我成功的唯一方法是编辑打印机高级属性,选择自定义 PostScript 格式,将其大小设置为上述大小,并且(强制!)将进纸方向设置为“短边优先”。(这些是 PDFCreator 选项。)
问题是,除非我没有找对地方,否则 Java Print API 中没有允许深入研究此类高级设置的选项!
请注意,我的最终目标是静默打印卡片,相当于禁用pjob.printDialog();
下面的条件。这是我正在寻找一种编程方式将这些条件应用于我的打印机设置的另一个原因。
备用解决方案可以包括模拟 legal 尺寸的纸张和打印卡片,就好像每页有四张 (3.5" × 4 = 14")。如果真的没有其他解决方案,我会尝试将其“出售”给我的客户,但这确实是不得已的选择……
任何想法都将不胜感激,如果有任何不够清楚的地方,请不要犹豫,要求更精确......
谢谢,
杰夫
import java.awt.print.PrinterJob;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
public class PrintTestClean {
public static void main(String[] args) {
printAwt();
}
private static PrintService getPrintService(String name) {
PrintService[] pss = PrintServiceLookup.lookupPrintServices(null, null);
for (PrintService ps : pss) {
if (name.equals(ps.getName())) {
return ps;
}
}
return null;
}
private static void printAwt() {
List<Card> cards = new ArrayList<Card>();
for (int i = 0; i < 1; i++) {
cards.add(new Card(new Date(), "Morin\nJean-François\nabcdefghijklmnopqrstuvwx", "Personnel de\nl'Université", "123 456 789", new Date()));
cards.add(new Card(new Date(), "Morin\nJean-François", "Étudiant", "123 456 789", new Date()));
}
try {
// Create Print Job
PrinterJob pjob = PrinterJob.getPrinterJob();
PrintService ps = getPrintService("PDFCreator");
if (ps != null) {
pjob.setPrintService(ps);
}
pjob.setJobName("test.pdf");
pjob.setPageable(new CardsLayout(cards));
// Send print job to default printer
//pjob.print(printRequestAttributeSet);
if (pjob.printDialog()) {
pjob.print();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
以下是上述程序引用的实用程序类:
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.util.List;
public class CardsLayout implements Printable, Pageable {
private static final Font FONT = new Font(Font.MONOSPACED, Font.PLAIN, 9);
private List<Card> cards;
private PageFormat pf = new PageFormat();
public CardsLayout(List<Card> pCards) {
cards = pCard;
Paper paper = new Paper();
// This is one of my countless tests to get a horizontal page layout...
//paper.setSize(252d, 612d);
//paper.setImageableArea(0d, 0d, 252d, 612d);
//pf.setOrientation(PageFormat.LANDSCAPE);
paper.setSize(612d, 252d);
paper.setImageableArea(0d, 0d, 612d, 252d);
pf.setOrientation(PageFormat.PORTRAIT);
pf.setPaper(paper);
}
@Override
public int getNumberOfPages() {
return cards.size();
}
@Override
public PageFormat getPageFormat(int pageIndex) throws IndexOutOfBoundsException {
return pf;
}
@Override
public Printable getPrintable(int pageIndex) throws IndexOutOfBoundsException {
return this;
}
@Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
if (pageIndex < 0 || pageIndex >= getNumberOfPages()) {
return NO_SUCH_PAGE;
}
int hligne = 10;
Card card = cards.get(pageIndex);
Graphics2D g2 = (Graphics2D) graphics;
g2.setFont(FONT);
int y = 99 - hligne;
for (String ligne : card.getName().split("\n")) {
g2.drawString(ligne, 95, y += hligne);
}
return PAGE_EXISTS;
}
}
import java.io.Serializable;
import java.util.Date;
public class Card implements Serializable {
private static final long serialVersionUID = 7739106764789216176L;
private Date expirationDate;
private String name;
private String status;
private String personId;
private Date birthDate;
public Card() {}
public Card(Date pExpirationDate, String pName, String pStatus, String pPersonId, Date pBirthDate) {
expirationDate = pExpirationDate;
name = pName;
status = pStatus;
personId = pPersonId;
birthDate = pBirthDate;
}
public Date getExpirationDate() {
return expirationDate;
}
public void setExpirationDate(Date pExpirationDate) {
expirationDate = pExpirationDate;
}
public String getName() {
return name;
}
public void setName(String pName) {
name = pName;
}
public String getStatus() {
return status;
}
public void setStatus(String pStatus) {
status = pStatus;
}
public String getPersonId() {
return personId;
}
public void setPersonId(String pPersonId) {
personId = pPersonId;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date pBirthDate) {
birthDate = pBirthDate;
}
}