1

I am developing an identity card management application in Java that will replace a decades-old obsolete mainframe system. The required functionalities include printing personal data on cards that are fed by a dot matrix printer. The page size of each card is 3.5" height × 8.5" width.

To illustrate my problem, the program below creates a two-page sample printout with some data.

  • I use PDFCreator as a printer, but I figured out that the behaviour is exactly the same with a dot matrix printer, so it can be tested by anyone reading this post.
  • The page size and layout are correct, but the pages are rotated 90° so that they are "fed" vertically.
  • On a laser printer, this would cause no problem since one would feed the sheets vertically as well (like Com-10 envelopes, for example). But this not acceptable with fanfold paper on a dot matrix printer.
  • By the way, this fanfold paper has a preprinted template, so no rotations are possible whatsoever.
  • Regardless of any page orientation option I use (i.e. putting an OrientationRequested parameter in a PrintRequestAttributeSet), it seems impossible to get the printout not to be rotated, i.e. to keep the 3.5" × 8.5" pages in their original horizontal orientation.
  • When running the program below, the only way I succeeded consists to edit the printer advanced properties, selected a custom PostScript format, set its size to the aforementioned size, and (MANDATORY!) set the paper feed direction to "Short Edge First." (These are PDFCreator options.)

The problem is, unless I am not looking at the right place, there are no options in the Java Print API that allow digging into such advanced settings!

Please note that my ultimate goal is to print cards silently, which is equivalent to disable the pjob.printDialog(); condition below. This is another reason for which I am looking for a programmatic way to apply such conditions to my printer settings.

A fallback solution could consist to simulate legal-sized paper and print cards as though there were four by page (3.5" × 4 = 14"). If there is really no other solution, I will try to "sell" it to my customers, but it is really a last-resort option...

Any ideas will be appreciated, and please don't hesitate to ask for more precisions if there is anything not clear enough...

Thanks,

Jeff

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();
    }
  }

}

Here are the utility classes referred to by the program above:

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;
  }

}
Jeff Morin
  • 1,010
  • 1
  • 13
  • 25
  • What is the make and model of the printer? – Ahmed Masud Feb 06 '12 at 22:11
  • It is a Lexmark Forms Printer 2490. I will have to do the same job on a Printronix P7210 high-capacity printer, which will be used to print batches of approximately 2000 cards. This is the main reason for my need to bypass the default long-edge-first behaviour (i.e. sheets are fed vertically), which is appropriate for ink-jet and laser printers. – Jeff Morin Feb 07 '12 at 13:39

0 Answers0