Multiple Page Counts / Group Page Count
I'm trying to have a page count per group on my reports.
For example, we have a report that prints a Move Order. A Move Order may have multiple pick slips (one per sub-inventory). I want to have a Move Order page count and a Pick Slip page count.
Does anybody have a way to do this?
Thanks,
You aren't really linking the frames to the pages. Simply set the "page break before" on the second frame. When the first frame finishes printing (regardless of how many pages that is) it will skip to the next page before the second frame starts printing. If required, you can make the page numbering re-set if you want to based on repeating frame values.
If you really want to distinguish between the layouts, you can create up to 3 layouts by using each of the three sections (header, main, trailer). As each section finishes, there is also a page break before the next section starts.
You can get at the page number using srw.get_page_num() but I don't think this will help you.
Similar Messages
-
Print JTable with Multiple pages and rows
I took the printing example at http://java.sun.com/developer/onlineTraining/Programming/JDCBook/advprint.html#pe and modified it a bit to include the following:
1) To Print Multiple pages
2) To wrap lines that is too long for the column
3) To print with a more proffesional style, so that it doesn't look like a screen capture is printed
4) To align the numbers to the right and center column headings
import javax.swing.*;
import javax.swing.table.*;
import java.awt.print.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.Dimension;
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import java.text.*;
public class Report implements Printable
private final int LEFT_ALIGN = -1;
private final int CENTER_ALIGN = 0;
private final int RIGHT_ALIGN = 1;
private JFrame frame;
private JTable tableView;
private String lastPrintDate;
private Font defaultFont;
private Font headerFont;
private Font footerFont;
private int headerHeight;
private int footerHeight;
private int cellBuffer = 5;
private boolean first_pass;
private ArrayList pages;
public Report()
frame = new JFrame("Sales Report");
frame.addWindowListener(new WindowAdapter()
public void windowClosing(WindowEvent e)
System.exit(0);
final String[] headers =
"ID",
"Description",
"open price",
"latest price",
"End Date",
"Quantity"
int count = 0;
final Object[][] data =
{new Integer(count++), "Box of BirosBox of BirosBox of BirosBox of BirosBox of BirosBox of BirosBox of BirosBox of BirosBox of BirosBox of BirosBox of BirosBox of BirosBox of BirosBox of Biros ppppppppppppppp", "1.00", "4.99", new Date(), new Integer(200000)},
{new Integer(count++), "Blue Biro", "0.10", "0.14", new Date(), new Integer(1)},
{new Integer(count++), "legal pad", "1.00", "2.49", new Date(), new Integer(1)},
{new Integer(count++), "tape", "1.00", "1.49", new Date(), new Integer(1)},
{new Integer(count++), "stapler", "4.00", "4.49", new Date(), new Integer(1)},
{new Integer(count++), "Box of Biros", "1.00", "4.99", new Date(), new Integer(2)},
{new Integer(count++), "Blue Biro", "0.10", "0.14", new Date(), new Integer(1)},
{new Integer(count++), "legal pad", "1.00", "2.49", new Date(), new Integer(1)},
{new Integer(count++), "tape", "1.00", "1.49", new Date(), new Integer(1)},
{new Integer(count++), "stapler", "4.00", "4.49", new Date(), new Integer(1)},
{new Integer(count++), "Box of Biros", "1.00", "4.99", new Date(), new Integer(2)},
{new Integer(count++), "Blue Biro", "0.10", "0.14", new Date(), new Integer(1)},
{new Integer(count++), "legal pad", "1.00", "2.49", new Date(), new Integer(1)},
{new Integer(count++), "tape", "1.00", "1.49", new Date(), new Integer(1)},
{new Integer(count++), "stapler", "4.00", "4.49", new Date(), new Integer(1)},
{new Integer(count++), "Box of Biros", "1.00", "4.99", new Date(), new Integer(2)},
{new Integer(count++), "Blue Biro", "0.10", "0.14", new Date(), new Integer(1)},
{new Integer(count++), "legal pad", "1.00", "2.49", new Date(), new Integer(1)},
{new Integer(count++), "tape", "1.00", "1.49", new Date(), new Integer(1)},
{new Integer(count++), "stapler", "4.00", "4.49", new Date(), new Integer(1)},
{new Integer(count++), "Box of Biros", "1.00", "4.99", new Date(), new Integer(2)},
{new Integer(count++), "Blue Biro", "0.10", "0.14", new Date(), new Integer(1)},
{new Integer(count++), "legal pad", "1.00", "2.49", new Date(), new Integer(1)},
{new Integer(count++), "tape", "1.00", "1.49", new Date(), new Integer(1)},
{new Integer(count++), "stapler", "4.00", "4.49", new Date(), new Integer(1)},
{new Integer(count++), "Box of Biros", "1.00", "4.99", new Date(), new Integer(2)},
{new Integer(count++), "Blue Biro", "0.10", "0.14", new Date(), new Integer(1)},
{new Integer(count++), "legal pad", "1.00", "2.49", new Date(), new Integer(1)},
{new Integer(count++), "tape", "1.00", "1.49", new Date(), new Integer(1)},
{new Integer(count++), "stapler", "4.00", "4.49", new Date(), new Integer(1)},
{new Integer(count++), "Box of Biros", "1.00", "4.99", new Date(), new Integer(2)}
TableModel dataModel = new AbstractTableModel()
public int getColumnCount() { return headers.length; }
public int getRowCount() { return data.length;}
public Object getValueAt(int row, int col)
return data[row][col];
public String getColumnName(int column)
return headers[column];
public Class getColumnClass(int col)
return getValueAt(0,col).getClass();
public boolean isCellEditable(int row, int col)
return (col==1);
public void setValueAt(Object aValue, int row, int column)
data[row][column] = aValue;
tableView = new JTable(dataModel);
JScrollPane scrollpane = new JScrollPane(tableView);
scrollpane.setPreferredSize(new Dimension(500, 80));
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(BorderLayout.CENTER,scrollpane);
frame.pack();
JButton printButton= new JButton();
printButton.setText("print me!");
frame.getContentPane().add(BorderLayout.SOUTH,printButton);
// for faster printing turn double buffering off
RepaintManager.currentManager(frame).setDoubleBufferingEnabled(false);
printButton.addActionListener( new ActionListener()
public void actionPerformed(ActionEvent evt)
doPrint();
frame.setVisible(true);
* Reset variables before printing
private void prepareForPrint()
pages = new ArrayList();
first_pass = true;
* Display a print dialog with some hardcoded defaults
* The print fonts are also hardcoded
public void doPrint()
try
String jobName = "Java Report";
defaultFont = new Font("Arial", Font.PLAIN, 8);
footerFont = new Font("Arial", Font.PLAIN, 6);
headerFont = new Font("Arial", Font.BOLD, 10);
PrinterJob prnJob = PrinterJob.getPrinterJob();
prnJob.setPrintable(this);
PrintRequestAttributeSet prnSet = new HashPrintRequestAttributeSet();
prnSet.add(new Copies(1));
prnSet.add(new JobName(jobName, null));
prnSet.add(MediaSizeName.ISO_A4);
PageFormat pf = prnJob.defaultPage();
pf.setOrientation(java.awt.print.PageFormat.PORTRAIT);
prnJob.setJobName(jobName);
PrintService[] services = PrinterJob.lookupPrintServices();
if (services.length > 0)
if (prnJob.printDialog(prnSet))
* Get print date
String dateFormat = "dd/MM/yyyy HH:mm:ss";
DateFormat m_DateFormat = new SimpleDateFormat(dateFormat);
lastPrintDate = m_DateFormat.format(new Date()).toString();
prepareForPrint();
prnJob.print(prnSet);
else
JOptionPane.showMessageDialog(frame, "No Printer was found!!", "Printer Error", JOptionPane.ERROR_MESSAGE);
return;
catch (PrinterException e)
e.printStackTrace();
public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException
* Check if this is the first time the print method is called for this print action.
* It is not guaranteed that the print will be called with synchronous pageIndex'es,
* so we need to calculate the number of pages and which rows appear on which pages.
* Then the correct page will be printed regardless of which pageIndex is sent through.
if (first_pass)
calcPages(g, pageFormat);
first_pass = false;
// Stop printing if the pageIndex is out of range
if (pageIndex >= pages.size())
return NO_SUCH_PAGE;
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.black);
// The footer will be one line at the bottom of the page, cater for this.
g2.setFont(footerFont);
footerHeight = g2.getFontMetrics().getHeight() + g2.getFontMetrics().getDescent();
g2.setFont(defaultFont);
FontMetrics fontMetrics = g2.getFontMetrics();
int fontHeight = fontMetrics.getHeight();
int fontDescent = fontMetrics.getDescent();
double pageHeight = pageFormat.getImageableHeight() + pageFormat.getImageableY();
double pageWidth = pageFormat.getImageableWidth();
double tableWidth = (double) tableView.getColumnModel().getTotalColumnWidth();
// Shrink or expand the table to fit the page width
double scale = pageWidth / (tableWidth+ (cellBuffer * tableView.getColumnCount()));
// Calculate the width in pixels for each column
double[] columnWidths = new double[tableView.getColumnCount()];
for(int i = 0; i < tableView.getColumnCount(); i++)
columnWidths[i] = (double)tableView.getColumnModel().getColumn(i).getWidth() * scale;
// Reset the view to the start of the page
g2.translate(0, 0);
// Draw a rectangle to see the printable area
g2.draw3DRect((int)pageFormat.getImageableX(),
(int)pageFormat.getImageableY(),
(int)pageFormat.getImageableWidth(),
(int)pageFormat.getImageableHeight(),
false);
// Calculate the header height
g2.setFont(headerFont);
fontMetrics = g2.getFontMetrics();
// Print the headers and retreive the starting position for the data
int next_row = printLine(g2, pageFormat, fontMetrics, -1, (int)pageFormat.getImageableY() + fontHeight, columnWidths);
g2.setFont(defaultFont);
fontMetrics = g2.getFontMetrics();
// Start printing the detail
ArrayList page = (ArrayList)pages.get(pageIndex);
int start = ((Integer)page.get(0)).intValue();
int end = ((Integer)page.get(1)).intValue();
for (int i = start; i <= end; i++)
next_row = printLine(g2, pageFormat, fontMetrics, i, next_row, columnWidths);
// Print the footer
g2.setFont(footerFont);
String pageFooter = "Page " + (pageIndex + 1) + " - " + lastPrintDate;
g2.drawString(pageFooter,
(int)pageFormat.getWidth() / 2 - (fontMetrics.stringWidth(pageFooter) / 2),
(int)(pageHeight - fontDescent));
return PAGE_EXISTS;
* We can't guarantee that the same amount of rows will be displayed on each page,
* the row heights are dynamic and may wrap onto 2 or more lines.
* Thus we need to calculate the height of each row and then test how may rows
* fit on a specific page. eg. Page 1 contains rows 1 to 10, Page 2 contains rows 11 to 15 etc.
public void calcPages(Graphics g, PageFormat pageFormat) throws PrinterException
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.black);
// The footer will be one line at the bottom of the page, cater for this.
g2.setFont(footerFont);
footerHeight = g2.getFontMetrics().getHeight() + g2.getFontMetrics().getDescent();
g2.setFont(defaultFont);
FontMetrics fontMetrics = g2.getFontMetrics();
int fontHeight = fontMetrics.getHeight();
int fontDescent = fontMetrics.getDescent();
double pageHeight = pageFormat.getImageableHeight() - fontHeight;
double pageWidth = pageFormat.getImageableWidth();
double tableWidth = (double) tableView.getColumnModel().getTotalColumnWidth();
// Shrink or expand the table to fit the page width
double scale = pageWidth / (tableWidth+ (cellBuffer * tableView.getColumnCount()));
// Calculate the width in pixels for each column
double[] columnWidths = new double[tableView.getColumnCount()];
for(int i = 0; i < tableView.getColumnCount(); i++)
columnWidths[i] = (double)tableView.getColumnModel().getColumn(i).getWidth() * scale;
// Calculate the header height
int maxHeight = 0;
g2.setFont(headerFont);
fontMetrics = g2.getFontMetrics();
for (int j = 0; j < tableView.getColumnCount(); j++)
String value = tableView.getColumnName(j).toString();
int numLines = (int)Math.ceil(fontMetrics.stringWidth(value) / columnWidths[j]);
if (numLines > maxHeight)
maxHeight = numLines;
headerHeight = g2.getFontMetrics().getHeight() * maxHeight;
g2.setFont(defaultFont);
fontMetrics = g2.getFontMetrics();
int pageNum = 0;
int bottom_of_page = (int)(pageFormat.getImageableHeight() + pageFormat.getImageableY()) - footerHeight;
int prev_row = 0;
int next_row = (int)pageFormat.getImageableY() + fontHeight + headerHeight;
int i = 0;
ArrayList page = new ArrayList();
page.add(new Integer(0));
for (i = 0; i < tableView.getRowCount(); i++)
maxHeight = 0;
for (int j = 0; j < tableView.getColumnCount(); j++)
String value = tableView.getValueAt(i, j).toString();
int numLines = (int)Math.ceil(fontMetrics.stringWidth(value) / columnWidths[j]);
if (numLines > maxHeight)
maxHeight = numLines;
prev_row = next_row;
next_row += (fontHeight * maxHeight);
// If we've reached the bottom of the page then set the current page's end row
if (next_row > bottom_of_page)
page.add(new Integer(i - 1));
pages.add(page);
page = new ArrayList();
page.add(new Integer(i));
pageNum++;
next_row = (int)pageFormat.getImageableY()
+ fontHeight
+ ((int)pageFormat.getHeight() * pageNum)
+ headerHeight;
bottom_of_page = (int)(pageFormat.getImageableHeight()
+ pageFormat.getImageableY())
+ ((int)pageFormat.getHeight() * pageNum)
- footerHeight;
//Include the current row on the next page, because there is no space on this page
i--;
page.add(new Integer(i - 1));
pages.add(page);
* Print the headers or a row from the table to the graphics context
* Return the position of the row following this one
public int printLine(Graphics2D g2,
PageFormat pageFormat,
FontMetrics fontMetrics,
int rowNum,
int next_row,
double[] columnWidths)
throws PrinterException
int lead = 0;
int maxHeight = 0;
for (int j = 0; j < tableView.getColumnCount(); j++)
String value = null;
int align = LEFT_ALIGN;
if (rowNum > -1)
Object obj = tableView.getValueAt(rowNum, j);
if (obj instanceof Number)
align = RIGHT_ALIGN;
value = obj.toString();
else
align = CENTER_ALIGN;
value = tableView.getColumnName(j);
int numLines = (int)Math.ceil(fontMetrics.stringWidth(value) / columnWidths[j]);
if (numLines > maxHeight)
maxHeight = numLines;
if (fontMetrics.stringWidth(value) < columnWidths[j])
// Single line
int offset = 0;
// Work out the offset from the start of the column to display alignment correctly
switch (align)
case RIGHT_ALIGN: offset = (int)(columnWidths[j] - fontMetrics.stringWidth(value)); break;
case CENTER_ALIGN: offset = (int)(columnWidths[j] - fontMetrics.stringWidth(value)) / 2; break;
default: offset = 0; break;
g2.drawString(value,
lead + (int)(pageFormat.getImageableX() + offset),
next_row);
else
for(int a = 0; a < numLines; a++)
//Multi-Line
int x = 0;
int width = 0;
for(x = 0; x < value.length(); x++)
width += fontMetrics.charWidth(value.charAt(x));
if (width > columnWidths[j])
break;
int offset = 0;
// Work out the offset from the start of the column to display alignment correctly
switch (align)
case RIGHT_ALIGN: offset = (int)(columnWidths[j] - fontMetrics.stringWidth(value)); break;
case CENTER_ALIGN: offset = (int)(columnWidths[j] - fontMetrics.stringWidth(value)) / 2; break;
default: offset = 0; break;
g2.drawString(value.substring(0, x),
lead + (int)(pageFormat.getImageableX() + offset),
next_row + (fontMetrics.getHeight() * a));
value = value.substring(x);
lead += columnWidths[j] + cellBuffer;
// Draw a solid line below the row
g2.draw(new Line2D.Double(pageFormat.getImageableX(),
next_row + (fontMetrics.getHeight() * (maxHeight - 1)) + fontMetrics.getDescent(),
pageFormat.getImageableY() + pageFormat.getImageableWidth(),
next_row + (fontMetrics.getHeight() * (maxHeight - 1)) + fontMetrics.getDescent()));
// Return the position of the row following this one
return next_row + (fontMetrics.getHeight() * maxHeight);
public static void main(String[] args)
new Report();
}Fixed some bugs and added a title. Just pass in a JTable and the class will do the rest.
import javax.swing.*;
import javax.swing.table.*;
import java.awt.print.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import java.text.*;
import java.math.*;
public class PrintJTable implements Printable
private final int LEFT_ALIGN = -1;
private final int CENTER_ALIGN = 0;
private final int RIGHT_ALIGN = 1;
private JFrame m_parent;
private String m_title;
private JTable tableView;
private String lastPrintDate;
private Font defaultFont;
private Font headerFont;
private Font footerFont;
private int headerHeight;
private int footerHeight;
private int cellBuffer = 5;
private boolean first_pass;
private ArrayList pages;
public PrintJTable(JFrame parent, JTable table)
m_parent = parent;
tableView = table;
doPrint();
public PrintJTable(JFrame parent, String title, JTable table)
m_parent = parent;
m_title = title;
tableView = table;
doPrint();
* Reset variables before printing
private void prepareForPrint()
pages = new ArrayList();
first_pass = true;
* Display a print dialog with some hardcoded defaults
* The print fonts are also hardcoded
public void doPrint()
try
String jobName = "Java Report";
defaultFont = new Font("Arial", Font.PLAIN, 8);
footerFont = new Font("Arial", Font.PLAIN, 6);
headerFont = new Font("Arial", Font.BOLD, 8);
PrinterJob prnJob = PrinterJob.getPrinterJob();
prnJob.setPrintable(this);
PrintRequestAttributeSet prnSet = new HashPrintRequestAttributeSet();
prnSet.add(new Copies(1));
prnSet.add(new JobName(jobName, null));
prnSet.add(MediaSizeName.ISO_A4);
PageFormat pf = prnJob.defaultPage();
pf.setOrientation(java.awt.print.PageFormat.PORTRAIT);
prnJob.setJobName(jobName);
PrintService[] services = PrinterJob.lookupPrintServices();
if (services.length > 0)
if (prnJob.printDialog(prnSet))
* Get print date
String dateFormat = "dd/MM/yyyy HH:mm:ss";
DateFormat m_DateFormat = new SimpleDateFormat(dateFormat);
lastPrintDate = m_DateFormat.format(new Date()).toString();
prepareForPrint();
prnJob.print(prnSet);
else
JOptionPane.showMessageDialog(m_parent, "No Printer was found!!", "Printer Error", JOptionPane.ERROR_MESSAGE);
return;
catch (PrinterException e)
e.printStackTrace();
public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException
* Check if this is the first time the print method is called for this print action.
* It is not guaranteed that the print will be called with synchronous pageIndex'es,
* so we need to calculate the number of pages and which rows appear on which pages.
* Then the correct page will be printed regardless of which pageIndex is sent through.
if (first_pass)
calcPages(g, pageFormat);
first_pass = false;
// Stop printing if the pageIndex is out of range
if (pageIndex >= pages.size())
return NO_SUCH_PAGE;
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.black);
// The footer will be one line at the bottom of the page, cater for this.
g2.setFont(footerFont);
footerHeight = g2.getFontMetrics().getHeight() + g2.getFontMetrics().getDescent();
g2.setFont(defaultFont);
FontMetrics fontMetrics = g2.getFontMetrics();
int fontHeight = fontMetrics.getHeight();
int fontDescent = fontMetrics.getDescent();
double pageHeight = pageFormat.getImageableHeight() + pageFormat.getImageableY();
double pageWidth = pageFormat.getImageableWidth();
double tableWidth = (double) tableView.getColumnModel().getTotalColumnWidth();
// Shrink or expand the table to fit the page width
double scale = (pageWidth - (cellBuffer * tableView.getColumnCount())) / tableWidth;
// Calculate the width in pixels for each column
double[] columnWidths = new double[tableView.getColumnCount()];
double test = 0;
for(int i = 0; i < tableView.getColumnCount(); i++)
columnWidths[i] = (double)Math.floor(tableView.getColumnModel().getColumn(i).getWidth() * scale);
test += columnWidths;
// Reset the view to the start of the page
g2.translate(0, 0);
// Draw a rectangle to see the printable area
g2.draw3DRect((int)pageFormat.getImageableX(),
(int)pageFormat.getImageableY(),
(int)pageFormat.getImageableWidth(),
(int)pageFormat.getImageableHeight(),
false);
// Calculate the header height
g2.setFont(headerFont);
fontMetrics = g2.getFontMetrics();
// Print the headers and retreive the starting position for the data
int next_row = (int)pageFormat.getImageableY() + fontMetrics.getHeight();
if ((m_title != null) && (!m_title.equalsIgnoreCase("")))
g2.drawString(m_title,
(int)(pageFormat.getImageableX()),
next_row);
Color current_color = g2.getColor();
g2.setColor(Color.lightGray);
int y = next_row + fontMetrics.getDescent();
g2.draw(new Line2D.Double(pageFormat.getImageableX(),
y,
(pageFormat.getImageableY() + pageFormat.getImageableWidth()),
y));
g2.setColor(current_color);
next_row += fontMetrics.getHeight();
next_row = printLine(g2, pageFormat, fontMetrics, -1, next_row, columnWidths);
g2.setFont(defaultFont);
fontMetrics = g2.getFontMetrics();
// Start printing the detail
ArrayList page = (ArrayList)pages.get(pageIndex);
int start = ((Integer)page.get(0)).intValue();
int end = ((Integer)page.get(1)).intValue();
for (int i = start; i <= end; i++)
next_row = printLine(g2, pageFormat, fontMetrics, i, next_row, columnWidths);
// Print the footer
g2.setFont(footerFont);
String pageFooter = "Page " + (pageIndex + 1) + " - " + lastPrintDate;
g2.drawString(pageFooter,
(int)pageFormat.getWidth() / 2 - (fontMetrics.stringWidth(pageFooter) / 2),
(int)(pageHeight - fontDescent));
return PAGE_EXISTS;
* We can't guarantee that the same amount of rows will be displayed on each page,
* the row heights are dynamic and may wrap onto 2 or more lines.
* Thus we need to calculate the height of each row and then test how may rows
* fit on a specific page. eg. Page 1 contains rows 1 to 10, Page 2 contains rows 11 to 15 etc.
public void calcPages(Graphics g, PageFormat pageFormat) throws PrinterException
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.black);
// The footer will be one line at the bottom of the page, cater for this.
g2.setFont(footerFont);
footerHeight = g2.getFontMetrics().getHeight() + g2.getFontMetrics().getDescent();
g2.setFont(defaultFont);
FontMetrics fontMetrics = g2.getFontMetrics();
int fontHeight = fontMetrics.getHeight();
int fontDescent = fontMetrics.getDescent();
double pageHeight = pageFormat.getImageableHeight() - fontHeight;
double pageWidth = pageFormat.getImageableWidth();
double tableWidth = (double) tableView.getColumnModel().getTotalColumnWidth();
// Shrink or expand the table to fit the page width
double scale = (pageWidth - (cellBuffer * tableView.getColumnCount())) / tableWidth;
// Calculate the width in pixels for each column
double[] columnWidths = new double[tableView.getColumnCount()];
for(int i = 0; i < tableView.getColumnCount(); i++)
columnWidths[i] = (double)Math.floor(tableView.getColumnModel().getColumn(i).getWidth() * scale);
// Calculate the header height
int maxHeight = 0;
g2.setFont(headerFont);
fontMetrics = g2.getFontMetrics();
headerHeight = 0;
if ((m_title != null) && (!m_title.equalsIgnoreCase("")))
headerHeight = fontMetrics.getHeight();
for (int j = 0; j < tableView.getColumnCount(); j++)
String value = tableView.getColumnName(j).toString();
int numLines = (int)Math.ceil(fontMetrics.stringWidth(value) / columnWidths[j]);
if (numLines > maxHeight)
maxHeight = numLines;
headerHeight += g2.getFontMetrics().getHeight() * maxHeight;
g2.setFont(defaultFont);
fontMetrics = g2.getFontMetrics();
int pageNum = 0;
int bottom_of_page = (int)(pageFormat.getImageableHeight() + pageFormat.getImageableY()) - footerHeight;
int prev_row = 0;
int next_row = (int)pageFormat.getImageableY() + fontHeight + headerHeight;
int i = 0;
ArrayList page = new ArrayList();
page.add(new Integer(0));
for (i = 0; i < tableView.getRowCount(); i++)
maxHeight = 0;
for (int j = 0; j < tableView.getColumnCount(); j++)
String value = formatObject(tableView.getValueAt(i, j));
int numLines = (int)Math.ceil(fontMetrics.stringWidth(value) / columnWidths[j]);
if (numLines > maxHeight)
maxHeight = numLines;
prev_row = next_row;
next_row += (fontHeight * maxHeight);
// If we've reached the bottom of the page then set the current page's end row
if (next_row > bottom_of_page)
page.add(new Integer(i - 1));
pages.add(page);
page = new ArrayList();
page.add(new Integer(i));
pageNum++;
next_row = (int)pageFormat.getImageableY()
+ fontHeight
+ ((int)pageFormat.getHeight() * pageNum)
+ headerHeight;
bottom_of_page = (int)(pageFormat.getImageableHeight()
+ pageFormat.getImageableY())
+ ((int)pageFormat.getHeight() * pageNum)
- footerHeight;
//Include the current row on the next page, because there is no space on this page
i--;
page.add(new Integer(i - 1));
pages.add(page);
* Print the headers or a row from the table to the graphics context
* Return the position of the row following this one
public int printLine(Graphics2D g2,
PageFormat pageFormat,
FontMetrics fontMetrics,
int rowNum,
int next_row,
double[] columnWidths)
throws PrinterException
int lead = 0;
int maxHeight = 0;
for (int j = 0; j < tableView.getColumnCount(); j++)
String value = null;
int align = LEFT_ALIGN;
if (rowNum > -1)
Object obj = tableView.getValueAt(rowNum, j);
if (obj instanceof Number)
align = RIGHT_ALIGN;
value = formatObject(obj);
else
//align = CENTER_ALIGN;
value = tableView.getColumnName(j);
int numLines = (int)Math.ceil(fontMetrics.stringWidth(value) / columnWidths[j]);
if (numLines > maxHeight)
maxHeight = numLines;
if (fontMetrics.stringWidth(value) < columnWidths[j])
// Single line
int offset = 0;
// Work out the offset from the start of the column to display alignment correctly
switch (align)
case RIGHT_ALIGN: offset = (int)(columnWidths[j] - fontMetrics.stringWidth(value)); break;
case CENTER_ALIGN: offset = (int)(columnWidths[j] - fontMetrics.stringWidth(value)) / 2; break;
default: offset = 0; break;
g2.drawString(value,
lead + (int)(pageFormat.getImageableX() + offset),
next_row);
else
for(int a = 0; a < numLines; a++)
//Multi-Line
int x = 0;
int width = 0;
for(x = 0; x < value.length(); x++)
width += fontMetrics.charWidth(value.charAt(x));
if (width > columnWidths[j])
break;
int offset = 0;
// Work out the offset from the start of the column to display alignment correctly
switch (align)
case RIGHT_ALIGN: offset = (int)(columnWidths[j] - fontMetrics.stringWidth(value.substring(0, x))); break;
case CENTER_ALIGN: offset = (int)(columnWidths[j] - fontMetrics.stringWidth(value.substring(0, x))) / 2; break;
default: offset = 0; break;
g2.drawString(value.substring(0, x),
lead + (int)(pageFormat.getImageableX() + offset),
next_row + (fontMetrics.getHeight() * a));
value = value.substring(x);
lead += columnWidths[j] + cellBuffer;
// Draw a solid line below the row
Color current_color = g2.getColor();
g2.setColor(Color.lightGray);
int y = next_row + (fontMetrics.getHeight() * (maxHeight - 1)) + fontMetrics.getDescent();
g2.draw(new Line2D.Double(pageFormat.getImageableX(),
y,
(pageFormat.getImageableY() + pageFormat.getImageableWidth()),
y));
g2.setColor(current_color);
// Return the position of the row following this one
return next_row + (fontMetrics.getHeight() * maxHeight);
public String formatObject(Object obj)
String value = (obj == null) ? "" : obj.toString();
return value; -
Dynamic table header/footer on multiple pages stay original
hi experts,
i've got a form with a dynamic table. this means that i have a footerrow with mapped information if it should be visible or not. so the table can have from 1 to 40 columns.
i did some scripting in the table's initialize section:
loop over count of colums and set the headerrow, row1 and footerrow elements for index x to hidden.
everything works out fine BUT if the data spans over multiple pages the headerrow on pages 2 to last is original again. means that the hiding of cells is not effective any more. same with footerrow (but here its fine at last page and original at page 1 to last -1).
i tried to hide cells again in layout:ready section for the other instances of the headerrow.
cells got hidden, but the still visible cells didnt relocate to the left (if i hide it, there should be no space between staying cells).
can anyone please give me a hint what i am missing here?
does anyone have a simple sample for this task? its all about the header/footer for multiple pages!
thanks a lot!
daapooWhen the footer goes to the 2nd page the page subform is incremented so you will have to reference the page subform as well. I suggest that you add a button (this is for a test only) to the footer subform and add the code app.alert(this.somExpression). Now render the form and make sure the footer stays on one page. Hit the button and take note of the someExpression. Now add enough rows to force the footer to a new page. Hit th ebutton again and take note of the changed somExpression. So to solve your problem you will have to find out which page your footer is on. and then construct your expression to incorporate this chane in expression. Note that the indexes are 0 based but the page numbering is 1 based.
Hope that helps
Paul -
Nested Tables and Multiple Pages
Hi,
I have a problem with nested tables that span multiple pages.
Lets assume I want to create a list of orders. Each order contains several order items. As long as an order contains less order items than fit to one page the list is rendered correctly. But if an order contain more items all items that can´t be displayed at the first page are cut off.
I´ve tried so many combinations of subforms with flow content and position content, subform sets and "Allow Page Breaks within Content" as well as Layout Property "Expand to fit" but nothing helped.
Can someone tell me if and how I can achieve this. In the meantime I do work in Designer directly with a XML datasource. So I could send you the form and example data.
I´m working with NW04 SP11 and Adobe Designer 6.0
Best regards
HelmutHello Helmut,
There are some limitations and bugs in your requirement.
Please see the output after copying into notepad.
1.Eventhough if you give overflow leader , the headers for item table will not repeat.it is a bug.this is not solved in designer 7.1 also.
2.There are some accessibilty bugs in case of nested table.
Please follow the below design in the hierachy tab.
MainTable (subform)
|---- Header (subform)
| |- Header texts for Main table +
| |- Text for nested table
|---- DATA_main (subform)
|-Main table fields
|-ITEMDATA ( Table SUBFORM)
|-Header (Subform)
| |-ItemHeader texts
|-DATA_item (subform)
|-Item data fields
for DATA_main and DATA_item subforms, set repeat count MIN in binding tab.Set all flow content and allow page break with in the content.
The output will appear in the following manner.
<b>( Copy the below text into the notepad. )</b>
<b>Order no. text customer
Order items</b>
=================================================================
1 Computer Mr. Smith
<b>Order item no. short text quantity price</b>
10 PC Tower 1 400.00
20 LCD Display 1 200.00
30 Keyboard 1 15.00
40 Mouse 1 10.00
2 Notebook Mrs. Parker
<b>Order item no. short text quantity price</b>
10 HP Notebook 1 600.00
20 Ext. hard drive 1 80.00
let me know if u didnt get the solution.
Thanks and Regards,
Pavan Meda -
Requisition line description (lengthy) span multiple pages
All,
I have a requirement to print a Requisition that has multiple lines and multiple rolled up distributions (for the first six segments) in a fixed area of the template. Each line item description appended with an attachment text must print in a confined area. Further, the bottom part contains some fixed text and a table printing rolled up distributions. The distributions could run into multiple pages as the space to print in the confined area is just 4 lines. An average scenario is a requisition with three lines (each line's item description is about 2500 characters) and maybe eight distributions.
Data relationship in the layout: One master (Requisition Header) and two details (one for lines and the other for distributions).
Layout (Font for the most part is Arial size 7)
Requisition Header information prints some fixed text and some dynamic text spanning 15 physical lines. The dynamic text in this section of the layout from header contains limited text that will fit in the layout.
Requisition Lines information prints line details in a confined area spanning 24 physical lines.
Part of the requisition header information print in a confined area spanning 25 physical lines.
Requisition Distribution information prints in a confined area spanning 4 physical lines.
At the bottom, three more physical lines of text from Requisition header information are expected.
I have been trying to use RTF template and I have not been able to achieve the above requirement. Any help is greatly appreciated.
Thanks in advance
GopalI don't know if this will be of any help or not but let me explain what I did to a form to get the text in some of the fields to continue on to the next page.
On my first page I have a sub form I call MainPage and within that sub form I have several sub forms that each contain a title bar and some descriptive text and an expandable text field. The specs for the MainPage sub form is as follows,
Object tab > Subform tab > Type: = Flow Content.
Object tab > Subform tab > Allow Page Breaks within Content is checked.
Object tab > Subform tab > After: = Continue Filling Parent.
Object tab > Binding tab > Repeat Subform for Each Data Item is checked and Min Count is set to 1.
Layout tab > Auto-fit for the Height is checked.
The specs for one of the subforms inside the MainPage sub form are,
Object tab > Subform tab > Type: = Position Content.
Object tab > Subform tab > Allow Page Breaks within Content is checked.
Object tab > Subform tab > After: = Continue Filling Parent.
Object tab > Binding tab > Repeat Subform for Each Data Item is checked and Min Count is set to 1.
Layout tab > Auto-fit for the Height is checked.
The specs for the expandable text field are,
Object tab > Field tab > Allow Multiple Lines and Allow Plain Text Only check boxes are both checked.
Layout tab > Expand to fit check box for the Height is checked only.
This set up works for me and I get a text field that continues onto the next page but I have noticed some strange things going on that make it work rather awkward. The scroll bars are odd and some times after adding a bunch of text and then I move out of the field a text overflow symbol shows up at the bottom of the continued field on the next page. When you come back and click on the field to add more text the scroll bar appears and you need to scroll to the end of the value that is allready in the field to continue typeing. -
Import XML table over multiple pages with rowspan "bug"
Hi, I came across the following oddity:
I have an XML-file, and a XSL-file to convert the XML-data into a table.
It contains a header, body & a footer.
This table, however, has a rowspan in the first column, spanning [x] rows, where [x] is the amount of items per category, like this example:
Header 1
Header 2
Header 3
Header 4
Header 5
Header 6
Appetizers (3 items)
Appetizers1
Appetizers2
Appetizers3
Soup and Salad (4 items)
Soup and Salad1
Soup and Salad2
Soup and Salad3
Soup and Salad4
Deserts (2 items)
Deserts1
Deserts2
Footer
This works fine, as long as all data fits on 1 page.
If I, for example, have 40 "soups & salads", and thus spanning more pages, the "rowspan" is NOT continued on the 2nd page!
This results into an odd-looking table.
I've included the sample-XML & XSL files to see it in practice, and I leave this post with the following question:
Am I missing something? Or is it 'something I have to live with, and edit things manually anyway?
XML:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="data_IDs.xsl"?>
<menu>
<section name="Appetizers">
<summary>Start your meal with something hot and fresh</summary>
<item>
<pcode>1001</pcode>
<title>Appetizer Title 1</title>
<description>Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada
erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit,
posuere a, pede.
</description>
<price>7</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Appetizer Title 2</title>
<description>Praesent dapibus, neque id cursus faucibus, tortor neque
egestas augue, eu vulputate magna eros eu erat. Aliquam erat
volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis
luctus, metus.
</description>
<price>8</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Appetizer Title 3</title>
<description>Suspendisse accumsan est quis enim accumsan consectetur.
Donec at turpis odio, at pharetra mauris. Ut suscipit dictum velit
eget faucibus. Fusce nulla justo, varius id gravida non, fermentum
non mi. Duis eget dui eget enim scelerisque mattis eu a dolor.
</description>
<price>6</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Appetizer Title 4</title>
<description>Pellentesque magna enim, pulvinar et luctus in,
facilisis non tellus. Ut vehicula, massa id viverra faucibus, leo
leo dictum augue, ut tempus est sapien in arcu. Vestibulum elementum
mollis libero vel sollicitudin. Vivamus tempus quam eu velit
facilisis fermentum.
</description>
<price>6</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Appetizer Title 5</title>
<description>Phasellus faucibus commodo sem, vitae tincidunt nulla
elementum at. Nulla mi nunc, aliquam sit amet gravida et, congue at
dui. Vestibulum blandit lorem at ipsum luctus viverra. Fusce congue
erat non mi euismod sed euismod est pulvinar.
</description>
<price>12</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Appetizer Title 1</title>
<description>Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada
erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit,
posuere a, pede.
</description>
<price>7</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Appetizer Title 2</title>
<description>Praesent dapibus, neque id cursus faucibus, tortor neque
egestas augue, eu vulputate magna eros eu erat. Aliquam erat
volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis
luctus, metus.
</description>
<price>8</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Appetizer Title 3</title>
<description>Suspendisse accumsan est quis enim accumsan consectetur.
Donec at turpis odio, at pharetra mauris. Ut suscipit dictum velit
eget faucibus. Fusce nulla justo, varius id gravida non, fermentum
non mi. Duis eget dui eget enim scelerisque mattis eu a dolor.
</description>
<price>6</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Appetizer Title 4</title>
<description>Pellentesque magna enim, pulvinar et luctus in,
facilisis non tellus. Ut vehicula, massa id viverra faucibus, leo
leo dictum augue, ut tempus est sapien in arcu. Vestibulum elementum
mollis libero vel sollicitudin. Vivamus tempus quam eu velit
facilisis fermentum.
</description>
<price>6</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Appetizer Title 5</title>
<description>Phasellus faucibus commodo sem, vitae tincidunt nulla
elementum at. Nulla mi nunc, aliquam sit amet gravida et, congue at
dui. Vestibulum blandit lorem at ipsum luctus viverra. Fusce congue
erat non mi euismod sed euismod est pulvinar.
</description>
<price>12</price>
<img>img1.jpg</img>
</item>
</section>
<section name="Soup and Salad">
<summary>Made with locally grown ingredients. Served with breadsticks.
</summary>
<item>
<pcode>1001</pcode>
<title>Soup 1</title>
<description>Phasellus faucibus commodo sem, vitae tincidunt nulla
elementum at. Nulla mi nunc, aliquam sit amet gravida et, congue at
dui. Vestibulum blandit lorem at ipsum luctus viverra. Fusce congue
erat non mi euismod sed euismod est pulvinar.
</description>
<price>5</price>
<img>img1.jpg</img>
<options></options>
<category>low fat, low calorie, heart healthy</category>
</item>
<item>
<pcode>1001</pcode>
<title>Soup 2</title>
<description>Pellentesque magna enim, pulvinar et luctus in,
facilisis non tellus. Ut vehicula, massa id viverra faucibus, leo
leo dictum augue, ut tempus est sapien in arcu. Vestibulum elementum
mollis libero vel sollicitudin. Vivamus tempus quam eu velit
facilisis fermentum.
</description>
<price>6</price>
<img>img1.jpg</img>
<options></options>
<category>gluten-free</category>
</item>
<item>
<pcode>1001</pcode>
<title>Soup 3</title>
<description>Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada
erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit,
posuere a, pede.
</description>
<price>6</price>
<img>img1.jpg</img>
<options>Quisque venenatis: +$2, Donec ultricies: +3.</options>
`
<category></category>
</item>
<item>
<pcode>1001</pcode>
<title>Salad 1</title>
<description>Praesent dapibus, neque id cursus faucibus, tortor neque
egestas augue, eu vulputate magna eros eu erat. Aliquam erat
volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis
luctus, metus.
</description>
<price>11</price>
<img>img1.jpg</img>
<options></options>
<category></category>
</item>
<item>
<pcode>1001</pcode>
<title>Salad 2</title>
<description>Suspendisse accumsan est quis enim accumsan consectetur.
Donec at turpis odio, at pharetra mauris. Ut suscipit dictum velit
eget faucibus. Fusce nulla justo, varius id gravida non, fermentum
non mi. Duis eget dui eget enim scelerisque mattis eu a dolor.
</description>
<price>9</price>
<img>img1.jpg</img>
<options>Quisque venenatis: +$2, Donec ultricies: +3.</options>
<category></category>
</item>
<item>
<pcode>1001</pcode>
<title>Salad 3</title>
<description>Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada
erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit,
posuere a, pede.
</description>
<price>14</price>
<img>img1.jpg</img>
<options>Quisque venenatis: +$2, Donec ultricies: +3.</options>
<category></category>
</item>
<item>
<pcode>1001</pcode>
<title>Soup 1</title>
<description>Phasellus faucibus commodo sem, vitae tincidunt nulla
elementum at. Nulla mi nunc, aliquam sit amet gravida et, congue at
dui. Vestibulum blandit lorem at ipsum luctus viverra. Fusce congue
erat non mi euismod sed euismod est pulvinar.
</description>
<price>5</price>
<img>img1.jpg</img>
<options></options>
<category>low fat, low calorie, heart healthy</category>
</item>
<item>
<pcode>1002</pcode>
<title>Soup 2</title>
<description>Pellentesque magna enim, pulvinar et luctus in,
facilisis non tellus. Ut vehicula, massa id viverra faucibus, leo
leo dictum augue, ut tempus est sapien in arcu. Vestibulum elementum
mollis libero vel sollicitudin. Vivamus tempus quam eu velit
facilisis fermentum.
</description>
<price>6</price>
<img>img1.jpg</img>
<options></options>
<category>gluten-free</category>
</item>
<item>
<pcode>1003</pcode>
<title>Soup 3</title>
<description>Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada
erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit,
posuere a, pede.
</description>
<price>6</price>
<img>img1.jpg</img>
<options>Quisque venenatis: +$2, Donec ultricies: +3.</options>
`
<category></category>
</item>
<item>
<pcode>1004</pcode>
<title>Soup 4</title>
<description>Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada
erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit,
posuere a, pede.
</description>
<price>6</price>
<img>img1.jpg</img>
<options>Quisque venenatis: +$2, Donec ultricies: +3.</options>
<category></category>
</item>
<item>
<pcode>1005</pcode>
<title>Soup 5</title>
<description>Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada
erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit,
posuere a, pede.
</description>
<price>6</price>
<img>img1.jpg</img>
<options>Quisque venenatis: +$2, Donec ultricies: +3.</options>
<category></category>
</item>
<item>
<pcode>1006</pcode>
<title>Soup 6</title>
<description>Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada
erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit,
posuere a, pede.
</description>
<price>6</price>
<img>img1.jpg</img>
<options>Quisque venenatis: +$2, Donec ultricies: +3.</options>
<category></category>
</item>
</section>
<section name="Main Courses">
<summary>Made with locally grown ingredients. Served with breadsticks.
</summary>
<item>
<pcode>1001</pcode>
<title>Main Course 1</title>
<description>Phasellus bibendum erat ac tellus laoreet id aliquam
quam ultrices.
</description>
<price>14</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Main Course 2</title>
<description>Pellentesque magna enim, pulvinar et luctus in,
facilisis non tellus. Ut vehicula, massa id viverra faucibus, leo
leo dictum augue, ut tempus est sapien in arcu. Vestibulum elementum
mollis libero vel sollicitudin. Vivamus tempus quam eu velit
facilisis fermentum.
</description>
<price>20</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Main Course 3</title>
<description>Donec accumsan nibh nec ligula iaculis sagittis. Cras
pellentesque consectetur libero, eu egestas turpis scelerisque quis.
In hac habitasse platea dictumst.
</description>
<price>16</price>
<img>img1.jpg</img>
<options></options>
`
<category></category>
</item>
<item>
<pcode>1001</pcode>
<title>Main Course 4</title>
<description>Cras ac mauris non lectus tincidunt tristique et eget
augue. Maecenas leo dolor, viverra et laoreet ut, sagittis in orci.
</description>
<price>11</price>
<img>img1.jpg</img>
<options>Quisque venenatis: +$2, Donec ultricies: +3.</options>
<category></category>
</item>
<item>
<pcode>1001</pcode>
<title>Main Course 5</title>
<description>Suspendisse accumsan est quis enim accumsan consectetur.
Donec at turpis odio, at pharetra mauris. Ut suscipit dictum velit
eget faucibus. Fusce nulla justo, varius id gravida non, fermentum
non mi. Duis eget dui eget enim scelerisque mattis eu a dolor.
</description>
<price>14</price>
<img>img1.jpg</img>
</item>
</section>
<section name="Desserts">
<summary>Delicious homemade deserts.</summary>
<item>
<pcode>1001</pcode>
<title>Dessert 1</title>
<description>Suspendisse accumsan est quis enim accumsan consectetur.
Donec at turpis odio, at pharetra mauris. Ut suscipit dictum velit
eget faucibus. Fusce nulla justo, varius id gravida non, fermentum
non mi. Duis eget dui eget enim scelerisque mattis eu a dolor.
</description>
<price>5</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Dessert 2</title>
<description>Suspendisse accumsan est quis enim accumsan consectetur.
Donec at turpis odio, at pharetra mauris. Ut suscipit dictum velit
eget faucibus. Fusce nulla justo, varius id gravida non, fermentum
non mi. Duis eget dui eget enim scelerisque mattis eu a dolor.
</description>
<price>7</price>
<img>img1.jpg</img>
</item>
<item>
<pcode>1001</pcode>
<title>Dessert 3</title>
<description>Suspendisse accumsan est quis enim accumsan consectetur.
Donec at turpis odio, at pharetra mauris. Ut suscipit dictum velit
eget faucibus. Fusce nulla justo, varius id gravida non, fermentum
non mi. Duis eget dui eget enim scelerisque mattis eu a dolor.
</description>
<price>6</price>
<img>img1.jpg</img>
</item>
</section>
</menu>
XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<!-- [items] = amount of data items from XML, AND 2 more for 1 header and
1 footer. It's needed to define the amount of table rows for aid:rows, for
table properties -->
<xsl:variable name="items" select="count(menu/section/item) + 2" />
<Root>
<Artikel>
<Tabel xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/"
aid:table="table" aid:trows="{$items}" aid:tcols="6">
<!-- [START TABLE HEADER] -->
<Cel aid:table="cell" aid:theader="" aid:crows="1" aid:ccols="1"
aid:ccolwidth="128.14829396300001">
<xsl:value-of select="$items" />
</Cel>
<Cel aid:table="cell" aid:theader="" aid:crows="1" aid:ccols="1"
aid:ccolwidth="49.36745406773224">ProductCode
</Cel>
<Cel aid:table="cell" aid:theader="" aid:crows="1" aid:ccols="1"
aid:ccolwidth="93.54330708661416">ProductNaam
</Cel>
<Cel aid:table="cell" aid:theader="" aid:crows="1" aid:ccols="1"
aid:ccolwidth="94.96062992125985">ProductOmschrijving
</Cel>
<Cel aid:table="cell" aid:theader="" aid:crows="1" aid:ccols="1"
aid:ccolwidth="46.77165354330708">ProductPrijs
</Cel>
<Cel aid:table="cell" aid:theader="" aid:crows="1" aid:ccols="1"
aid:ccolwidth="356.09842519608674">ProductFoto
</Cel>
<!-- [END TABLE HEADER] -->
<!-- [START TABLE BODY] -->
<xsl:for-each select="menu/section">
<xsl:variable name="products" select="count(item)" />
<Cel aid:table="cell" aid:crows="{$products}" aid:ccols="1"
aid:ccolwidth="128.14829396300001">
<xsl:value-of select="@name" />
<xsl:value-of select="$products" />
<!-- <Afbeelding href="file:///Images/img1.jpg" /> -->
</Cel>
<xsl:for-each select="item">
<Cel aid:table="cell" aid:crows="1" aid:ccols="1"
aid:ccolwidth="49.36745406773224">
<xsl:value-of select="pcode" />
</Cel>
<Cel aid:table="cell" aid:crows="1" aid:ccols="1"
aid:ccolwidth="93.54330708661416">
<xsl:value-of select="title" />
</Cel>
<Cel aid:table="cell" aid:crows="1" aid:ccols="1"
aid:ccolwidth="94.96062992125985">
<xsl:value-of select="title" />
</Cel>
<Cel aid:table="cell" aid:crows="1" aid:ccols="1"
aid:ccolwidth="46.77165354330708">
<xsl:value-of select="price" />
</Cel>
<Cel aid:table="cell" aid:crows="1" aid:ccols="1"
aid:ccolwidth="356.09842519608674">
<xsl:value-of select="normalize-space(title)" />
<!-- Let's tackle one problem at the time. Description contains a lot of text possibly causing another preflight-problem.
<xsl:value-of select="normalize-space(description)" /> -->
</Cel>
</xsl:for-each>
</xsl:for-each>
<!-- [END TABLE BODY] -->
<!-- [START TABLE FOOTER] -->
<Cel aid:table="cell" aid:tfooter="" aid:crows="1" aid:ccols="6">
<Afbeelding href="file:///Images/img1.jpg" />
</Cel>
<!-- [END TABLE FOOTER] -->
</Tabel>
</Artikel>
</Root>
</xsl:template>
</xsl:stylesheet>@Indesign developers: If you feed Indesign a table that spans acros multiple pages, it's expected that rowspans are continued on the next page.
For the next update?
Preferably with the option to repeat contense of that spanning cell. Like this:
<Page 1>
Header 1
Header 2
Header 3
Header 4
Header 5
Header 6
Appetizers (3 items)
Appetizers1
Appetizers2
Appetizers3
Soup and Salad (40 items)
Soup and Salad1
Soup and Salad2
Soup and Salad36
Footer
</Page 1>
<Page 2>
Header 1
Header 2
Header 3
Header 4
Header 5
Header 6
Soup and Salad (40 items)
Soup and Salad37
Soup and Salad38
Soup and Salad39
Soup and Salad40
Deserts (2 items)
Deserts1
Deserts2
Footer
</Page 2> -
Looping Cfdocument to produce a multiple page doc
Can anyone point out where I can find information on
producing a multiple
page cfdocument (pdf) using a database to include unique
information?
I have a customer that wants mailers that have the customers
name and
special offer. I want to use CF to generate the PDF doc using
a database as
the source. I will need to set up the document and then loop
it through each
database entry to create a multiple page document with the
information on
it.
Where can I find good information on how to do that?
Thanks.
Wally Kolcz
Developer / SupportSomething like this:
<cfdocument>
<cfoutput query="abc" group="somthing">
<cfdocumentsection>
stuff
<cfoutput>
more stuff
closing tags -
How to set a template to multiple pages
Hello,
I'm using Oracle Portal 10.1.2.0.2 and I've created a hiearchy of pages and a template with regions for banner, navigation portlet and content area and I want to set up this template to multiple pages. Manually and uncomfortably, I can edit my page and in [Template] tab in [Properties] select my template. But how can I do it for example for a whole page group? Default template for page group doesn't work for me - though I've set up it in page group, in a particular page I still see [Page template]=none with no effect. Is it possible to do it through some sql query? (With specification of region, in which the page will be mapped?)
Thank you for your advice,
tbObservation:
Pages from one page group can't see templates from another page group. In case of multiple page groups I have to put my templates in [Shared objects]. Unfortunately I didn't find a way (if even exists) how to copy template from one page group to another, especially to shared objects :( -
Implementing multiple page size requirement - extra blank page at the end
My XMLP report requirement is as follows.
- The report is printing a bunch of lines.
- Based on data and layout requirement, lines are grouped into page where they belong (due to complex logic for determining which page a line should go to...this is done in PL/SQL package that is called in the beginning of the RDF trigger)
- The first page needs to be printed on Legal size paper
- Subsequent pages (IF NEEDED) need to be printed on Letter size paper
So some report will have a 1-page output (legal size), and some will have multiple pages (1st page should be legal size, subsequent on letter size).
Here is a sample XML data:
<REPORT>
<LIST_G_PAGE_NUMBER>
<G_PAGE_NUMBER>
<PAGE_NUMBER>1</PAGE_NUMBER>
<LIST_G_LINE>
<G_LINE>...</G_LINE>
<G_LINE>...</G_LINE>
</LIST_G_LINE>
</G_PAGE_NUMBER>
<G_PAGE_NUMBER>
<PAGE_NUMBER>2</PAGE_NUMBER>
<LIST_G_LINE>
<G_LINE>...</G_LINE>
<G_LINE>...</G_LINE>
</LIST_G_LINE>
</G_PAGE_NUMBER>
<G_PAGE_NUMBER>
<PAGE_NUMBER>3</PAGE_NUMBER>
<LIST_G_LINE>
<G_LINE>...</G_LINE>
<G_LINE>...</G_LINE>
</LIST_G_LINE>
</G_PAGE_NUMBER>
</LIST_G_PAGE_NUMBER>
</REPORT>
For this, I created 2-pages RTF template and using the Word Page Setup feature:
1. First page setup is legal size (go to Page Setup, Paper tab, choose Letter and choose Apply to "Whole Document").
The first page has the following XMLP tag:
<?for-each: G_PAGE_NUMBER?>
<?if: PAGE_NUMBER=1?><?call:body?><?end if?>
<?end for-each?>
<?template:body?>
for-each loop that prints lines in a tabular format
<?end template?>
2. Second page setup is letter size (go to Page Setup, Paper, choose Letter and choose Apply to "This point forward").
<?for-each: G_PAGE_NUMBER?>
<?if: PAGE_NUMBER>1?><?call:body?><-- Ctrl-Break to insert a page break here --> <?end if?>
<?end for-each?>
It almost worked, except there is a blank page printed at the end. How do I remove the blank page? I have tried to use <?split-by-page-break:?> instead of the Ctrl-Break, but it did not seem to work (there is no page break happening at all).
I think the extra page is due to the multiple page nature of the RTF template. Is there a way to control the page size through XMLP tag (or XSL-FO). With that, I can try having a single page template and put the page size control within the XMLP / XSL-FO tag and hope that the extra blank page at the end will go away. Can someone please help?
Thank you!Sorry for the typo in my previous post... I meant Ctrl-Enter (not Ctrl-Break).
-
Multiple page library in one site
is there any way to create more than one page library in the same site programmatically in SharePoint 2013??
Mohamed AbdeenThere is no way to create multiple Pages libraries in a site. You can now create folders in your Pages Library to separate out different pages, but you can only have one Pages library per site collection because of the way it interfaces with other
features in the site.
Paul Stork SharePoint Server MVP
Principal Architect: Blue Chip Consulting Group
Blog: http://dontpapanic.com/blog
Twitter: Follow @pstork
Please remember to mark your question as "answered" if this solves your problem. -
Need to select and move images across multiple pages...
Hi,
I am using Indesign CS2 on a Windows machine and have a 25 page document with 4-up photos (4"X6") on individual pages. I used the ImageCatalog javascript to load these images so I don't seem to have any control from the Master page. I would like to group and move these images to a different location on their own pages.
Do you know how to select these images across multiple pages? Or can a simple script be written to process this task?
Thanks in advance for your help.
-GregHi Greg,
A script can certainly do what you want to do--but you have to be a bit more specific. Do you want to move them to different pages in some predefined way, or do you just want to adjust them a bit on the pages they're already on?
Thanks,
Ole -
How to print multiple pages in single spool in smartforms
Hi all,
I have a issue on to print multiple pages in single spool,i can able to print multiple pages in multiple spool .I am doing Check Print smartforms in that i need to print Multiple pages in single spool.Currently i am using the below code please help to solve this issue.
IF gv_tabix = 1.
lwa_outp_option-tdnewid = 'X'.
ELSE.
lwa_outp_option-tdnewid = ' '.
ENDIF.
Thanks,
DeesanthHi
TABLES: spfli.
DATA:
t_spfli type STANDARD TABLE OF spfli.
DATA:
fs_spfli TYPE spfli.
DATA:
w_form TYPE tdsfname,
w_flag TYPE i,
f_nam TYPE rs38l_fnam,
w_input TYPE ssfcompin,
w_control TYPE ssfctrlop.
SELECTION-SCREEN BEGIN OF BLOCK blk WITH FRAME.
SELECT-OPTIONS s_carrid FOR spfli-carrid.
SELECTION-SCREEN END OF BLOCK blk .
SELECTION-SCREEN BEGIN OF BLOCK block1 WITH FRAME.
PARAMETERS:
p_single RADIOBUTTON GROUP rad1,
p_ind RADIOBUTTON GROUP rad1.
SELECTION-SCREEN END OF BLOCK block1.
START-OF-SELECTION.
PERFORM display_data.
PERFORM ssf_function_module_name.
PERFORM spool_request.
*& Form display_data
* text
* --> p1 text
* <-- p2 text
FORM display_data .
SELECT * FROM spfli INTO TABLE t_spfli WHERE carrid IN s_carrid.
ENDFORM. " display_data
*& Form ssf_function_module_name
* text
* --> p1 text
* <-- p2 text
FORM ssf_function_module_name .
CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
EXPORTING formname = ' '
IMPORTING fm_name = f_nam
EXCEPTIONS no_form = 1
no_function_module = 2.
* IF sy-subrc NE 0.
* MESSAGE 'Form cannot be displayed' TYPE 'E' .
* ENDIF. " IF sy-subrc eq 0
ENDFORM. " ssf_function_module_name
*& Form spool_request
* text
* --> p1 text
* <-- p2 text
FORM spool_request .
w_input-dialog = 'X'.
CALL FUNCTION 'SSFCOMP_OPEN'
EXPORTING input = w_input
EXCEPTIONS error = 1.
*" LOOP AT t_spfli .....................................................
LOOP AT t_spfli INTO fs_spfli.
w_control-no_open = ' '.
w_control-no_close = ' '.
*"Single spool request..................................................
IF p_single EQ 'X'.
w_control-no_open = 'X'.
w_control-no_close = 'X'.
ELSE.
*"Individual spool request.............................................
IF w_flag NE '1'.
w_control-no_open = 'X'.
w_control-no_close = ' '.
w_flag = 1.
CALL FUNCTION ' '
EXPORTING control_parameters = w_control
fs_spfli = fs_spfli
EXCEPTIONS formatting_error = 1
internal_error = 2
send_error = 3
user_canceled = 4.
endif. " IF w_flag ne '1'
ENDIF. " IF p_single eq 'X'.
CALL FUNCTION ' '
EXPORTING
control_parameters = w_control
fs_spfli = fs_spfli
EXCEPTIONS formatting_error = 1
internal_error = 2
send_error = 3
user_canceled = 4.
ENDLOOP. " LOOP at t_spfli into ...
*&This function module close the spool request *
CALL FUNCTION 'SSFCOMP_CLOSE'
EXCEPTIONS error = 1.
ENDFORM. " spool_request
Regards,
Sravanthi -
Multiple Page Report (Invoice)
Good Morning,
I work for a healthcare orginzation and I am creating an invoice for services. The invoice has many lines and runs onto multiple pages. I am farily new to Crystal but I want to know if there is a way to have the Report Header and Footers print on a new page after so many lines of data are acheived.
I used the following forumula in both the detail sections and report header and report footer sections under Paging, New Page After, but the report header and footer do not appear on the consective pages.
If Remainder (RecordNumber, 15) = 0 then true else false
Is there another way to accomplish this?Thanks! What I ended up doing is having to create groups since I needed information broken down by different payers. Same concept with group headers and footers. I appreciate the response.
-
I have similar issue with the white pages on the SQL Server 2012 Report Builder
3.0. I created a multiple pages invoice report based on
XML data file, which contains about 80 pages per report. The report runs good. But when try the Print Layout ,(PDF file too) some white space happened on the top of report bodies among or after page 70th of the report combines with the First letter
"R" of Invoiced Company Name. Such as: "R Delivery Inc." or "Rock ..." , " Rose ..." " ,,," means names continues. (The report is sorted with Company name, and company ID). After "R".
(The page # changes based on the "R" name s position in the report), and the white space happens before "R" and jump up and down after. When the Other Letter shows up such like "S", the report text position goes normal until the
end of report, the white space will be gone after "R". I tried all methods those I could find online to reset the page margins, page breaks, LTrim, RTirm Company names, setting of page breaks. So far all the method meet "R"
will be no cure. (Even I set page break between each instance of a group, company names as “Rock...” and “Rose...“ are still set on same page. I am wondering, does the SQL Server 2012 Report Builder has pages limitation? Or The Letter "R"
has some bugs hide behind? Please help!Hi Helen,
As per my understanding, I think this issue is caused by width size is not appropriate in the report. To narrow down this issue, please make sure that Body Width + Left margin + Right margin <= (Page width).
If the tablix is a matrix, because of the column group can expand to multiple columns, we should according to the following rule:
Body Width + Extra expanded column width + Left margin + Right margin <= (Page width).
Besides, please make sure there are no extra page breaks before each “R”. To check whether the issue is caused by the letter “R”, we can try to use another field to replace the Company Name field.
Hope this helps.
Thanks,
Katherine Xiong
Katherine Xiong
TechNet Community Support -
Table not going across multiple pages
I have two simple side-by-side tables that I want to stretch across multiple pages when necessary by clicking the Add Another button object.
I think I've done everything necessary to have the table repeat on multiple pages:
1. My table is in a subform.
2. The subform is set to Flowed.
3. The table has Allow Page Breaks with Content
4. The table is not a group table
5. I have the Rows in Binding to Repeat Row for Each Data Item
What I do notice is that when I click on either Table and then click the Pagination tab in Object--- Pagination is greyed out
Can anyone offer any suggestions?
Thank you.Hi,
first of all thanks for the link to the tutorial
function(){return A.apply(null,[this].concat($A(arguments)))}
Niall O'Donovan wrote:
Example of building dynamic tables here: http://assure.ly/gk8Q7a.
I have created a header on my master-page (just a Logo-picture). When my dynamic table reaches the end of the page, it creates a new page - any problem yet.
But on the new page, the table just starts directly on the top (y = 0). In this way the table is placed above my logo.
Is there any way to solve this problem?
Anything like "check if there is a header on master page and set new rows on next table under the header"? -
Spreading a single form across multiple pages
I'd like to implement a single record form that spreads it's items across multiple pages for the purpose of grouping related information on each page such as "Contact Details"," Education Profile" etc. There are way too many columns for a single page.
In Oracle forms you can create a form across multiple canvases or on different tabs of a tabbed canvas. Each item has a property to position it on which canvas.
Is this possible in ApEx? I can see that transaction processing could be complex.
How do I avoid, for example, inserting the record a second time if I commit from a different page?
Any comments appreciated.
Paul PAnother way to do this without javascript and ajax that works pretty well is to setup a list that represents the logical "sections" and display it as a sidebar list.
Create a hidden item on the page called PX_ACTIVE_SECTION and set the visibility of each region on the page based on the value of this item. For example: :PX_ACTIVE_SECTION = 'Contact Details'. You can also have multiple regions associated with a single tab. Set the default value to whatever section you wish to display first.
Next, set each list item to be "current" when :PX_ACTIVE_SECTION is equal to that item ('Contact Details', 'Education Profile', etc.). Also set the URL destination of each item to: javascript:doSubmit('section name');
Finally, add a branch back to the current page that sets PX_ACTIVE_SECTION to &REQUEST.. This traps the doSubmit call so you can set the hidden item. (Add a condition, if needed, to prevent this branch from executing due to other buttons and requests).
The result is that the user can switch freely between sections and save after all data is entered. The page does refresh (since it doesn't use AJAX), but if your regions aren't too big, it should be reasonable.
Maybe you are looking for
-
HI, I am trying to see if i can bring a Workflow Process for Transaction F-03 (restricting the Users and make it go through an Approval Process to clear more than say $100).. I understood that i would need to have the Parking Functionality for
-
Problem in mapping sap bw server with Visual composer
I tried to create a module.. but the sap bw server is not mapping with visual composer. is any need to have special authorization for that.. if any please mention the authorization and role to be given to get mapping of bw server with visual composer
-
I have duplicate pictures in my camera roll and photo stream. If I turn off photo stream will I loose pictures in both areas?
-
Calc manager v11.1.2.1 error during execution
We have an issue with some of the rulesets which fails execution although there no issues during validation. The rules run fine individually but error when executed via ruleset. The error in the calcmanager execution log is as below. Import the rules
-
Trigger audio playback of file
I would like to create a language book but so far haven't seen how to trigger an audio file to play. an example would be if I created a Interactive image and when I click on a label it would show text and play file.