Print Report with multiple copies

i have an one page report called Receipt voucher which is in
format of form. I have an query. I have to take four prints of same report. but the problem is that if i take print of 1st copy it should appear on report like origional-Customer,2nd time- Accounts,3rd time - Sales Dept., and 4th time Book copy.so is there any logic from which i can do this.
Plz help me How can i Do this?

Hi Paromita,
If I understand your problem correctly then, here is the summary of your problem -
a) There are multiple tabs on selection screen. Out of which the first tab has a mandatory field i.e., Material Number. And then there are other tabs.
b) So, unless and until you provide the value in first tab for the material number(which is a mandatory field), you cannot navigate to the second tab or any other tab for that matter.
So, ideally the second and rest of other tabs are mutually dependent on the first tab's information as it has a mandatory field. Unless and until you make the first tab inactive it will not let you enter data in the second tab and so on.
So, to ideally enable input in second tab, make the first tab inactive. Try this and let me know if it works.
BR,
Ravi

Similar Messages

  • Report with multiple Detail Area

    Hi All,
    Please see the Report pointed to the link below:
    [Report with multiple Detail Area|http://us.share.geocities.com/felix5ac/fairway.jpg]
    Some Explanations:
    ========================
    (1) The line with "ABCDEFGH..." is variable data coming from the database in the Detail Area
    (2) The lines with "WBLNX'" "123, 123.12", 
                             "WBLNX'"
       are variable data associated with the same Heading: "ABCDEFGH..."
    (2b) There can be multiple lines of data in the detail area (i.e. 1 or more "ABCDEFGH..." and the associated WBLNX and numbers...)
    (3) Item Code Descriptions ==> is a Header Info
    (4) ARL ... and FPHI... ==> are variable data and lines in these area can be 1 line; it can be 4 lines; it can be 10 lines...
    (5) Lines FROM "Artwork Procedures..." to the the end of the page are static.
    QUESTION:
    ===================
    How do I best design these Report with the multiple detail areas? Again, please see link of the Report above...
    Thanks and Best regards,
    Felix

    Hi Felix
    You can place the less detailed fields in the regular sections of the report and wherever you require multiple lines you can use the subreports.
    Hope this helps.
    Regards
    Nikhil

  • Bursting a report with multiple queries

    Hi,
    I need to set-up bursting in BIP for a report with multiple queries. The output format is pdf and delivery is through e-mail. Since the queries need to be linked, I'm trying to do this using data template. I've set-up split and burst based on a field (store_id) from the first query which is used as a bind variable in the subsequent queries. So I'd ideally want the report to be split based on store_id. The report works fine if I use a parameter for store_id and view the output by store_id. When I try to schedule the report for bursting, it generates and e-mails the reports but only the last report appears to have correct data output while the others have only the output from the first query (and all other queries appear to return nothing in the report).
    Any suggestions on what could be the issue here? Thanks!
    Here is the data template for the report:
    <dataTemplate name="Report" description="Report" dataSourceRef="ReportDB">
    <dataQuery>
    <sqlStatement name="STORE_VENDOR">
    <![CDATA[SELECT STORE.STORE_ID Q1_STORE_ID, VENDOR.VENDOR_ID Q1_VENDOR_ID, VENDOR.VENDOR_DESC Q1_VENDOR_DESC, PERSON.NAME Q1_NAME
                   FROM STORE, SERVICE_TICKET, VENDOR, ROLE, ROLE_TYPE, PERSON, PERIOD PERIOD_FROM, PERIOD PERIOD_TO
                   WHERE (SERVICE_TICKET.SOURCE_ID = STORE.SOURCE_ID AND SERVICE_TICKET.STORE_ID = STORE.STORE_ID)
                   AND (SERVICE_TICKET.SOURCE_ID = VENDOR.SOURCE_ID AND SERVICE_TICKET.VENDOR_ID = VENDOR.VENDOR_ID)
                   AND (STORE.SOURCE_ID = ROLE.SOURCE_ID AND STORE.STORE_ID = ROLE.STORE_ID)
                   AND (ROLE.SOURCE_ID = ROLE_TYPE.SOURCE_ID AND ROLE.ROLE_TYPE_ID = ROLE_TYPE.TYPE_ID AND ROLE_TYPE.TYPE_DESC = 'PIC')
                   AND (ROLE.SOURCE_ID = PERSON.SOURCE_ID AND ROLE.PERSON_ID = PERSON.PERSON_ID)
                   AND SERVICE_TICKET.START_DATE BETWEEN PERIOD_FROM.START_DATE AND PERIOD_TO.END_DATE
                   AND PERIOD_FROM.PERIOD_DESC = 'Cal Week 1'
                   AND PERIOD_TO.PERIOD_DESC = 'Cal Week 4'
                   GROUP BY STORE.STORE_ID, VENDOR.VENDOR_ID, VENDOR.VENDOR_DESC, PERSON.NAME
                   ORDER BY STORE.STORE_ID]]>
    </sqlStatement>
    <sqlStatement name="WO">
    <![CDATA[SELECT STORE.STORE_ID Q3_STORE_ID, 'Nightly Cleaning' Q3_NIGHTLY_CLEANING, 'Nightly Cleaning' Q3_DESCRIPTION, SERVICE_TICKET.TICKET_ID Q3_TICKET_ID, TO_CHAR(SERVICE_TICKET.END_DATE, 'MM/DD/YYYY') Q3_END_DATE, 'Excellent' Q3_QUALITY_RATING_1, 'Satisfactory' Q3_QUALITY_RATING_2, 'Unsatisfactory' Q3_QUALITY_RATING_3
                   FROM SERVICE_TICKET, STORE, PERIOD PERIOD_FROM, PERIOD PERIOD_TO
                   WHERE (SERVICE_TICKET.SOURCE_ID = STORE.SOURCE_ID AND SERVICE_TICKET.STORE_ID = STORE.STORE_ID)
                   AND SERVICE_TICKET.START_DATE BETWEEN PERIOD_FROM.START_DATE AND PERIOD_TO.END_DATE
                   AND STORE.STORE_ID = :Q1_STORE_ID
                   AND PERIOD_FROM.PERIOD_DESC = 'Cal Week 1'
                   AND PERIOD_TO.PERIOD_DESC = 'Cal Week 4']]>
    </sqlStatement>
    <sqlStatement name="SERVC_TYPE_1">
    <![CDATA[SELECT STORE.STORE_ID Q4_STORE_ID, ZONE.ZONE_DESC Q4_ZONE_DESC, SERVICE_TICKET_LINE.SERVICE_COST Q4_SERVICE_COST, SERVICE_TICKET_LINE.TICKET_ID Q4_TICKET_ID, TO_CHAR(SERVICE_TICKET_LINE.WO_END_DATE, 'MM/DD/YYYY') Q4_WO_END_DATE, 'Excellent' Q4_QUALITY_RATING_1, 'Satisfactory' Q4_QUALITY_RATING_2, 'Unsatisfactory' Q4_QUALITY_RATING_3
                   FROM SERVICE_TICKET_LINE, SERVICE_TICKET, STORE, SERVICE_TYPE, ZONE, PERIOD PERIOD_FROM, PERIOD PERIOD_TO
                   WHERE (SERVICE_TICKET.SOURCE_ID = SERVICE_TICKET_LINE.SOURCE_ID AND SERVICE_TICKET.TICKET_ID = SERVICE_TICKET_LINE.TICKET_ID)
                   AND (SERVICE_TICKET.SOURCE_ID = STORE.SOURCE_ID AND SERVICE_TICKET.STORE_ID = STORE.STORE_ID)
                   AND (SERVICE_TICKET_LINE.SOURCE_ID = SERVICE_TYPE.SOURCE_ID AND SERVICE_TICKET_LINE.SERVICE_TYPE_ID = SERVICE_TYPE.TYPE_ID)
                   AND (SERVICE_TICKET_LINE.SOURCE_ID = ZONE.SOURCE_ID AND SERVICE_TICKET_LINE.ZONE_ID = ZONE.ZONE_ID)
                   AND SERVICE_TYPE.TYPE_DESC = 'ABC'
                   AND SERVICE_TICKET.START_DATE BETWEEN PERIOD_FROM.START_DATE AND PERIOD_TO.END_DATE
                   AND STORE.STORE_ID = :Q1_STORE_ID
                   AND PERIOD_FROM.PERIOD_DESC = 'Cal Week 1'
                   AND PERIOD_TO.PERIOD_DESC = 'Cal Week 4'
                   ORDER BY SERVICE_TICKET_LINE.SOURCE_ID, SERVICE_TICKET_LINE.TICKET_ID, SERVICE_TICKET_LINE.LINE_ID]]>
    </sqlStatement>
    <sqlStatement name="SERVC_TYPE_2">
    <![CDATA[SELECT STORE.STORE_ID Q5_STORE_ID, ZONE.ZONE_DESC Q5_ZONE_DESC, SERVICE_TICKET_LINE.SERVICE_COST Q5_SERVICE_COST, SERVICE_TICKET_LINE.TICKET_ID Q5_TICKET_ID, TO_CHAR(SERVICE_TICKET_LINE.WO_END_DATE, 'MM/DD/YYYY') Q5_WO_END_DATE, 'Excellent' Q5_QUALITY_RATING_1, 'Satisfactory' Q5_QUALITY_RATING_2, 'Unsatisfactory' Q5_QUALITY_RATING_3
                   FROM SERVICE_TICKET_LINE, SERVICE_TICKET, STORE, SERVICE_TYPE, ZONE, PERIOD PERIOD_FROM, PERIOD PERIOD_TO
                   WHERE (SERVICE_TICKET.SOURCE_ID = SERVICE_TICKET_LINE.SOURCE_ID AND SERVICE_TICKET.TICKET_ID = SERVICE_TICKET_LINE.TICKET_ID)
                   AND (SERVICE_TICKET.SOURCE_ID = STORE.SOURCE_ID AND SERVICE_TICKET.STORE_ID = STORE.STORE_ID)
                   AND (SERVICE_TICKET_LINE.SOURCE_ID = SERVICE_TYPE.SOURCE_ID AND SERVICE_TICKET_LINE.SERVICE_TYPE_ID = SERVICE_TYPE.TYPE_ID)
                   AND (SERVICE_TICKET_LINE.SOURCE_ID = ZONE.SOURCE_ID AND SERVICE_TICKET_LINE.ZONE_ID = ZONE.ZONE_ID)
                   AND SERVICE_TYPE.TYPE_DESC = 'XYZ'
                   AND SERVICE_TICKET.START_DATE BETWEEN PERIOD_FROM.START_DATE AND PERIOD_TO.END_DATE
                   AND STORE.STORE_ID = :Q1_STORE_ID
                   AND PERIOD_FROM.PERIOD_DESC = 'Cal Week 1'
                   AND PERIOD_TO.PERIOD_DESC = 'Cal Week 4'
                   ORDER BY SERVICE_TICKET_LINE.SOURCE_ID, SERVICE_TICKET_LINE.TICKET_ID, SERVICE_TICKET_LINE.LINE_ID]]>
    </sqlStatement>
    <sqlStatement name="SERVC_TYPE_3">
    <![CDATA[SELECT STORE.STORE_ID Q6_STORE_ID, ZONE.ZONE_DESC Q6_ZONE_DESC, 'Excellent' Q6_QUALITY_RATING_1, 'Satisfactory' Q6_QUALITY_RATING_2, 'Unsatisfactory' Q6_QUALITY_RATING_3, 'One' Q6_QTY_MISSING_1, 'Two' Q6_QTY_MISSING_2, '3 or More' Q6_QTY_MISSING_3
                   FROM SERVICE_TICKET_LINE, SERVICE_TICKET, STORE, SERVICE_TYPE, ZONE, PERIOD PERIOD_FROM, PERIOD PERIOD_TO
                   WHERE (SERVICE_TICKET.SOURCE_ID = SERVICE_TICKET_LINE.SOURCE_ID AND SERVICE_TICKET.TICKET_ID = SERVICE_TICKET_LINE.TICKET_ID)
                   AND (SERVICE_TICKET.SOURCE_ID = STORE.SOURCE_ID AND SERVICE_TICKET.STORE_ID = STORE.STORE_ID)
                   AND (SERVICE_TICKET_LINE.SOURCE_ID = SERVICE_TYPE.SOURCE_ID AND SERVICE_TICKET_LINE.SERVICE_TYPE_ID = SERVICE_TYPE.TYPE_ID)
                   AND (SERVICE_TICKET_LINE.SOURCE_ID = ZONE.SOURCE_ID AND SERVICE_TICKET_LINE.ZONE_ID = ZONE.ZONE_ID)
                   AND SERVICE_TYPE.TYPE_DESC = 'PQR'
                   AND SERVICE_TICKET.START_DATE BETWEEN PERIOD_FROM.START_DATE AND PERIOD_TO.END_DATE
                   AND STORE.STORE_ID = :Q1_STORE_ID
                   AND PERIOD_FROM.PERIOD_DESC = 'Cal Week 1'
                   AND PERIOD_TO.PERIOD_DESC = 'Cal Week 4'
                   ORDER BY SERVICE_TYPE.TYPE_ID]]>
    </sqlStatement>
    </dataQuery>
    <dataStructure>
         <group name="G_STORE_VENDOR" source="STORE_VENDOR">
              <element name="Q1_STORE_ID" value="Q1_STORE_ID"/>
              <element name="Q1_VENDOR_ID" value="Q1_VENDOR_ID"/>
              <element name="Q1_VENDOR_DESC" value="Q1_VENDOR_DESC"/>
              <element name="Q1_NAME" value="Q1_NAME"/>
         </group>     
         <group name="G_WO" source="WO">
              <element name="Q3_NIGHTLY_CLEANING" value="Q3_NIGHTLY_CLEANING"/>
              <element name="Q3_DESCRIPTION" value="Q3_DESCRIPTION"/>
              <element name="Q3_TICKET_ID" value="Q3_TICKET_ID"/>
              <element name="Q3_END_DATE" value="Q3_END_DATE"/>
              <element name="Q3_QUALITY_RATING_1" value="Q3_QUALITY_RATING_1"/>
              <element name="Q3_QUALITY_RATING_2" value="Q3_QUALITY_RATING_2"/>
              <element name="Q3_QUALITY_RATING_3" value="Q3_QUALITY_RATING_3"/>
         </group>     
         <group name="G_SERVC_TYPE_1" source="SERVC_TYPE_1">
              <element name="Q4_ZONE_DESC" value="Q4_ZONE_DESC"/>
              <element name="Q4_SERVICE_COST" value="Q4_SERVICE_COST"/>
              <element name="Q4_TICKET_ID" value="Q4_TICKET_ID"/>
              <element name="Q4_WO_END_DATE" value="Q4_WO_END_DATE"/>
              <element name="Q4_QUALITY_RATING_1" value="Q4_QUALITY_RATING_1"/>
              <element name="Q4_QUALITY_RATING_2" value="Q4_QUALITY_RATING_2"/>
              <element name="Q4_QUALITY_RATING_3" value="Q4_QUALITY_RATING_3"/>
         </group>     
         <group name="G_SERVC_TYPE_2" source="SERVC_TYPE_2">
              <element name="Q5_ZONE_DESC" value="Q5_ZONE_DESC"/>
              <element name="Q5_SERVICE_COST" value="Q5_SERVICE_COST"/>
              <element name="Q5_TICKET_ID" value="Q5_TICKET_ID"/>
              <element name="Q5_WO_END_DATE" value="Q5_WO_END_DATE"/>
              <element name="Q5_QUALITY_RATING_1" value="Q5_QUALITY_RATING_1"/>
              <element name="Q5_QUALITY_RATING_2" value="Q5_QUALITY_RATING_2"/>
              <element name="Q5_QUALITY_RATING_3" value="Q5_QUALITY_RATING_3"/>
         </group>     
         <group name="G_SERVC_TYPE_3" source="SERVC_TYPE_3">
              <element name="Q6_ZONE_DESC" value="Q6_ZONE_DESC"/>
              <element name="Q6_QUALITY_RATING_1" value="Q6_QUALITY_RATING_1"/>
              <element name="Q6_QUALITY_RATING_2" value="Q6_QUALITY_RATING_2"/>
              <element name="Q6_QUALITY_RATING_3" value="Q6_QUALITY_RATING_3"/>
              <element name="Q6_QTY_MISSING_1" value="Q6_QTY_MISSING_1"/>
              <element name="Q6_QTY_MISSING_2" value="Q6_QTY_MISSING_2"/>
              <element name="Q6_QTY_MISSING_3" value="Q6_QTY_MISSING_3"/>
         </group>
    </dataStructure>
    </dataTemplate>

    Hello user6428199,
    When you use ":Q1_STORE_ID" in your queries, BI Publisher looks for a report parameter named Q1_STORE_ID. Change all your report queries to get data for all the store_id's available. As you are bursting the report using the store_id as the bursting key, BI Publisher will split the report based on the stored_id and delivers content based on it. No matter how many queries you may have, BI Publisher will loop through all the store_id's available and all the queries will return data for that particular id in a report.
    Thanks,
    Machaan

  • Report with Multiple queries too slow in BI Publisher 11g

    Hi, I have a report in 11g where i need to create multiple queries to show them in report. I tried to combine everything in one query, but i found that the query is too huge and hard to understand and maintain. I created 3 data sets and linked them together. In SQL dev, the main query is returning about 315 records and first detail query returns less than 100 records and second detail query is returning one record which is BLOB. Each query returns data within a couple of seconds from SQL Developer. The entire report from BI Publisher should be just 21 page PDF output. Did anyone face performance issues while running reports with multiple queries in 11g? I ran reports that have single query which returned 10K pages PDF and never had an issue while everthing is in one query. This is the first time Iam attempting to create multiple queries. Can someone help me understand what i might be doing wrong or missing here. Thank you.

    Isn't there a way for you to do this via a Package/Procedure versus having multiple queries?
    Per the BI Publisher guide,
    Following are recommended guidelines for building data models:
    Reduce the number of data sets or queries in your data model as much as possible. In general, the fewer data sets and queries you have, the faster your data model will run. While multiquery data models are often easier to understand, single-query data models tend to execute more quickly. It is important to understand that in parent-child queries, for every parent, the child query is executed.
    You should only use multiquery data models in the following scenarios:
    To perform functions that the query type, such as a SQL query, does not support directly.
    To support complex views (for example, distributed queries or GROUP BY queries).
    To simulate a view when you do not have or want to use a view.
    Thanks,
    Bipuser

  • Report with multiple dimensions in Row and Column with EvEXP

    Hi
    We are currently running BPC 7.0 SP3 and try to create the report(or schedule) with more 2 x 2 dimensions in the row and column.
    e.g.
    row dimension : Outer row is Entity, Inner row is Account
    column dimension : Outer column is Time, Inner row is Category
    We created the report with  2 x 2 dimensions like above e.g. with EvEXP and EvNXP, NOT EvDRE
    based on default dynamic template:Template13.xlt(Nested Row, 2 x 1 dimensions defined by EvEXP and EvNXP formula).
    However, when expanding the dimension with double click these dimensions or change CV of the report with  2 x 2 dimensions defined by EvEXP and EvNXP formula,
    error occurs on EvEXP and EvNXP formula and can't retrieve the result correctly.
    [Question]
    Can't we create the report with more 2 x 2 dimensions in the row and column using EvEXP and EvNXP function ?
    We understand that we can make the report with more 2 x 2 dimensions in the row and column if using EvDRE.
    Thank You in advance
    Kenya

    Thank you for your advice.
    I understand that we should use EvDRE when creating the report with multiple dimension in the row/column because EvEXP have some erros, poor performance, etc.
    Then, we have two questions.
    1)
    >plus they had some errors in the designs.
    what kind of errors they have as an example?
    2)
    >If you must build the EVEXP and EVNXP, I would suggest building the template from scratch
    We built the simple template with just 2 x 2 dimension from scratch.
    But this report doesn't work well when double-click the dimension or changing CV...
    Would you please check the following template?
    <https://sapmats-de.sap-ag.de/download/download.cgi?id=RCZE1ME4YSORY3DCDO4NNMANZLBL1L5ZBUOB2F71YVNVS8XDJW>
    It would be greatly appreciated if you could give me your advice for the template.
    Thank you again
    And my best regards,
    Kenya

  • Report with multiple tabs

    Hi,
    I have a report with multiple tabs in selection screen. Say material number is mandatory in the first tab. But we don't need material number in the second tab. But if I want to go to the 2nd tab, i get the error message 'Please enter the material number'. Can this be avoided?
    Thanks in advance.

    Hi Paromita,
    If I understand your problem correctly then, here is the summary of your problem -
    a) There are multiple tabs on selection screen. Out of which the first tab has a mandatory field i.e., Material Number. And then there are other tabs.
    b) So, unless and until you provide the value in first tab for the material number(which is a mandatory field), you cannot navigate to the second tab or any other tab for that matter.
    So, ideally the second and rest of other tabs are mutually dependent on the first tab's information as it has a mandatory field. Unless and until you make the first tab inactive it will not let you enter data in the second tab and so on.
    So, to ideally enable input in second tab, make the first tab inactive. Try this and let me know if it works.
    BR,
    Ravi

  • Publication for Deski report with multiple data providers

    Hi,
    Has anyone been able to get a publication working that uses a Deski report with multiple data providers as the source? I'm trying to get a publication working that uses dynamic recipients and personalization. When I try to schedule the publication, I get the error "Object not found". 
    Thanks,
    Debbie

    Debbie,
    That's standard.
    It's useful for emulating outer joins in reports.
    Say you've got a sales report where you want to display all 12 months of the year in a crosstab whatever month you run in.
    We're only in May at the moment though. With one data provider (SALES), you'll get a crosstab with just up to May for your months.
    If you create a separate data provider called MONTHS to return the months in the current year, you will then have a merged dimension of YearMonth in both.
    In your crosstab if you just use YearMonth you'll get just the five months. If you qualify it with its data provider name (in our case MONTHS), you'll see the full twelve months shown.
    I hope that clears it up for your.
    Regards,
    Mark

  • Hyperion Anaylzer - how to Print report with information in pages?

    Hi,<BR><BR>I use Hyperion Analyzer Version: 6.1.1.00206 (from Help | About menu).<BR><BR>I created report with pages (on Navigate button selected the Pages). In pages are months (January, February, March, etc).<BR><BR>Now I would like to print current report. So I did:<BR>1. click on arrow beside Print button<BR>2. Print Current Report windows is displayed. I selected default options and press OK button.<BR><BR>Report is printed, but there is no page information printed out. So on paper there is report without months (January, February, March, etc).<BR><BR>How to print report with information in pages?<BR><BR>Thanks,<BR>Grofaty

    Jia Shun,
    I had the same issue for printing A/R Invoices - I created a Crystal Report based on a SQL View, works fine with A/R Invoice document, but the Draft Invoice printing has 3 pages: 1st page blank, 2nd page with watermark "DRAFT", 3rd page my Crystal Report layout without any data. When printing normally it is only 1 page.
    Here is what I did as a work around:
    Create two SQL Views, one select from OINV (joining INV1 and other tables needed), the other select from ODRF (joining DRF1 and other tables needed), for the draft printing.
    Create two identicle Crystal Reports, only difference are: datasource location (from different views), the "draft" crystal report has a watermark section.
    Go to Administration>System Initialization>Print Preferences and uncheck "Print draft watermark..."
    Import both crystal reports. Invoice can be printed normally. But the Draft Invoice has more steps: Open Draft document report, change settings so it shows the DocEntry in the Draft Table. Select and open the desired document, hit Print Preview, and enter the DocEntry, it displays the layout with data and "DRAFT" watermark.
    This is a workaround. I don't like it because it is not scalable - too much workload if you want to print 100 invoices.
    Hopefully someone will provide a better solution.
    regards,
    G

  • BI+ Reporting With Multiple Data Sources

    Hi -
    We've been using BI+ Reports with multiple data sources on separate grids. We are wondering if there is a better way to ensure the user has their point of view bar in sync between the the data sources. In our case, both Data Sources are separate HFM applications with all the dimensions identical except the account which is defined on the report. We are not using Metadata Management.
    I'm aware of the "Merge Equivalent Prompts" in the Preferences > Financial Reporting window, but this does not always ensure the users have the same point of view.
    What practice are other companies using to make sure the user runs the reports accurately with both point of view bars pulling the same entity/year/period.
    Thanks in advance.

    Thanks for your answer, however my question - I know it looks quite messy - is not directly related to data templates, my problem is that at the moment I am using a stored procedure following - almost exactly - what another procedure does in oracle EBS to call a BI publisher report.
    1. This procedure populates some temporary table with the xml data where the concurrent request picks it up and uses it to populate the BI publisher template.
    2. However I can't go and specify the XML location in my data template as this is not an option for us (i.e. reading the xml from the temporary table), so I am looking for another way to populate the BI publisher template (Note: I can't as well include the SQL queries in my Data template).
    Thanks ;)

  • Each page to be printed with multiple copies

    I have the following requirement:
    Each page of a document has to printed in the following way:
    at first the page is printed on paper from the standard paper tray
    then the same page is printed on special paper from a second paper tray.
    The print controls for the paper trays are clear.
    The problem is to print each page multiple times
    and to feed the paper from different trays for the different copies.
    And to get it sorted in that order!
    And to get it in one spool item.
    Is there a solution with SAP-Script/Smartforms or any other way?

    Frank,
    Pls look carefully this code which meets exactly your requirement.
    CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
                EXPORTING
                  formname           = w_form
                IMPORTING
                  fm_name            = w_fmname
                EXCEPTIONS
                  no_form            = 1
                  no_function_module = 2
                  OTHERS             = 3.
              IF sy-subrc <> 0.
                MESSAGE e899(5at) WITH 'Smartform call fails'.
              ENDIF.
              CALL FUNCTION w_fmname
                EXPORTING
                  control_parameters = ls_control_param
                  wa_vbrk            = wa_vbrk
                  wa_adrc            = wa_adrc
                  wa_j_1imocomp      = wa_j_1imocomp
                  wa_kna1            = wa_kna1
                  l_consignee        = l_consignee
                  l_name_co          = l_name_co_e
                  wa_adrc_l          = wa_adrc_l_e
                  l_j_1icht1         = l_j_1icht1_e
                  l_grnd_pcs         = l_grnd_pcs_e
                  l_grnd_fa          = l_grnd_fa_e
                  l_amtsum           = l_amtsum_e
                  wa_j_1iexchdr      = wa_j_1iexchdr_e
                  l_vbelv            = l_vbelv_e
                  l_wadat_ist        = l_wadat_ist_e
                  wa_j_1imocomp_l    = wa_j_1imocomp_l_e
                  l_name1            = l_name1_e
                  l_traid            = l_traid_e
                  wa_j_1imocust_l    = wa_j_1imocust_l_e.
    FORM set_print_param  CHANGING cs_control_param TYPE ssfctrlop.
      DATA:    ls_itcpo     TYPE itcpo,
               cf_retcode   TYPE sy-subrc,
               lf_repid     TYPE sy-repid,
               lf_device    TYPE tddevice.
      lf_repid = sy-repid.
      CALL FUNCTION 'WFMC_PREPARE_SMART_FORM'
        EXPORTING
          pi_nast             = nast
    *     PI_ADDR_KEY         = ' '
    *     PI_COUNTRY          = ' '
          pi_repid            = lf_repid
    *     PI_SCREEN           = ' '
       IMPORTING
          pe_returncode = cf_retcode
          pe_itcpo      = ls_itcpo
          pe_device     = lf_device.
    *      pe_recipient  = cs_recipient
    *      pe_sender     = cs_sender.
      IF cf_retcode = 0.
        cs_control_param-device      = lf_device.
        cs_control_param-no_dialog   = 'X'.
        cs_control_param-preview     = xscreen.
        cs_control_param-getotf      = ls_itcpo-tdgetotf.
        cs_control_param-langu       = nast-spras.
      ENDIF.
    ENDFORM.                    " set
    FORM sub_fill_copy .
      IF w_juri = 'KOLKATA'.
        t_copy-copy = 'ORIGINAL FOR BUYER'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'DUPLICATE FOR TRANSPORTER'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'TRIPLICATE FOR ASSESSE'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'EXTRA COPY'.
        APPEND t_copy.
        CLEAR  t_copy.
      ELSEIF w_juri = 'BEHROR'.
        t_copy-copy = 'ORIGINAL FOR BUYER'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'DUPLICATE FOR TRANSPORTER'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'TRIPLICATE FOR ASSESSE'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'EXTRA COPY'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'EXTRA COPY'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'EXTRA COPY'.
        APPEND t_copy.
        CLEAR  t_copy.
      ELSEIF w_juri = 'RUDRAPUR'.
        t_copy-copy = 'ORIGINAL FOR BUYER'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'DUPLICATE FOR TRANSPORTER'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'TRIPLICATE FOR ASSESSE'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'EXTRA COPY'.
        APPEND t_copy.
        CLEAR  t_copy.
      ELSEIF w_juri = 'MON'.
        t_copy-copy = 'ORIGINAL FOR BUYER'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'DUPLICATE FOR TRANSPORTER'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'TRIPLICATE FOR ASSESSE'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'EXTRA COPY'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'EXTRA COPY'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'EXTRA COPY'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'EXTRA COPY'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'EXTRA COPY'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'EXTRA COPY'.
        APPEND t_copy.
        CLEAR  t_copy.
        t_copy-copy = 'EXTRA COPY'.
        APPEND t_copy.
        CLEAR  t_copy.
      ENDIF.
    Amit.

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

  • Report with multiple choice in column for same dimension......

    Hi All,
    We have a report with two dimensions in col , one in row remaining in pov...user want to select multiple members [its more than 10 members..so we thought prompts will not be good.] for one column for different members in second dimension of column and want see the variance between them.
    can anyone suggest me how can i achieve this. thank you
    regards,
    Ravi

    Hi All,
    Can any one suggest me on this. thanks inadvance.
    Regards,
    Ravi

  • Problems with multiple copies of each photo

    I'm relatively new at using Photoshop Elements and when I was moving my photos from my old computer to my new one using an external hard drive I got multiple copies when I uploaded them to my new computer. How do I avoid this?
    I think that I had the same photos in diffrent files on the external hard drive and thus got them four times on my new computer. Do I need to sit and erase them by hand(it's 13 000!!) or what do I do. I cann't just let them be, they take up way too much space on the computer.
    How do I do not to make the same mistake again the next time I need to move them?
    This probably is a silly problem when you are used to the program but we are all beginners some time I guess! Hope you can help me...

    You can stack the duplicate images and delete the stack.While deleting the stack, application asks which photos present in the stack you need to delete. The stack can be formed from automatically suggest stacks and then you can stack them at one place. You can try this thing first with a small group of images.

  • After downloading music and dragging into iTunes I end up with multiple copies of the album on my hard drive. I do have the "copy files into iTunes library" checked. When I try to erase one of the copies I end up with red ! in iTunes library.

    Please Help!  After downloading an album and dragging it into itunes I end up having multiple copies of the album on my hard drive.  I do have (under Itunes preferences, advanced) copy songs into itunes library "checked".  I'm sure this is the reason for the multiple copies.  When I try to delete one of the copies of the album and go back to itunes and try playing a song, I get a red exclamtion point next to the song with an error message saying itunes cannot locate file. My questions are, Does Itunes literally make a copy of the song? If so , How do you know which file to delete?

    Sony's own entertainment software on the Vaio plays merry **** with iTunes, worse there's no telling when it will kick in.
    First head over to the Sony Vaio site and get the update for the software, that will stop it from messing with the iTunes database/library files when you connect your iPod.
    http://support.apple.com/kb/TS2715
    http://esupport.sony.com/US/perl/swu-download.pl?mdl=VGNP588EQ&updid=4526&osid=28
    With that stopped you can add the music back without fear of this happening again.

  • Creating a report with multiple Y-axes on one graph

    I currently have a script that will create a report with either 1, 2, or 3 graphs and has the ability to have four graphs per plot.  I would like to add functionality to this script by making the Y-axis on the graphs have multiple Y-axes.  How can I programmatically create a graph with multiple Y-axes?

    To create an new axis system use the command GraphObjNew, eg:
    Call GraphObjNew("2D-Axis","2DAxis1")
    Call GraphObjOpen("2DAxis1")        
      D2AxisBackColor = "blue"  
    Call GraphObjClose("2DAxis1") 
    Call PicUpdate
    If you have DIAdem Version 10 you can also create a new y-axis using GraphObjYAxisNew. This command is not available in versions 9.1:
    Call GraphObjOpen("2DAxis1")
    AxisNo = GraphObjYAxisNew("left")
    If AxisNo>0 Then
      Call GraphObjOpen(D2AxisYObj(AxisNo))
      D2AXISYTXT ="My new axis"
      D2AXISYTXTFONT ="Arial"
      D2AXISYTXTCOLOR ="red"
      Call GraphObjClose(D2AxisYObj(AxisNo))
    End If
    Call GraphObjClose("2DAxis1")
    Winfried
    Message Edited by winner on 03-23-2006 03:48 PM

Maybe you are looking for

  • Movies not showing up in cloud

    I have several movies such as The Hunger Games, Alien: The Director's Cut and some others that I purchased from iTunes.  However, on my iPad they are not showing up as downloadable from the cloud and when I look on my computer, iTunes store also does

  • Can't install on mac 10.10.4

    Hi, Im using mac pro however trying to download spotify on my mac to install but after it shows can not be open....the version is os x yosemite 10.10.4..., hope somebody can help work it out, thx.

  • XML Digital Signature API: creation of SignatureProperties

    Hallo! I'm having problems using the XMLDigitalSignature API to create signature properties. I want my signature to contain the following <SignatureProperties>             <SignatureProperty Id="testID" Target="testTarget">                 testConten

  • How to make a link in textflow that send parameters to a function?

    How to make a link in textflow that send parameters to a function?

  • Trouble sending files through ichat after 10.4.7 update

    after the 10.4.7 update (at least it was right around the same time as the update), my ichat stopped being able to send files to my friend. the picture or video would appear to be sending, but the next time i said something, i would be informed that