Upload
enkitec
View
1.039
Download
14
Embed Size (px)
DESCRIPTION
Citation preview
Printing with APEX: PL/PDF
Scott SpendoliniExecutive Director, Enkitec
1
� Scott Spendolini
� @sspendol
� Ex-Oracle Employee of 10 years
� Senior Product Manager for Oracle APEXfrom 2002 through 2005
� Founded Sumner Technologiesin October 2005
� Co-Founded Sumneva in January 2010
� Joined Enkitec in June 2012
� Oracle Ace Director
� Author, Expert Oracle Application Express Security
� Co-Author, Pro Oracle Application Express
� “Scott” on OTN Forums
About the Presenter
2
Agenda� Overview
� Installation
� Integration
� Implementation
� Security
� Summary
4
OVERVIEW
5
What is PL/PDF?
6
�Third party product designed by Oranext
� http://plpdf.com
�Provides a set of PL/SQL based APIs that can generate PDF files from the Oracle database
�Easy to securely integrate with APEX
�Can be called from a Page or Application Process
PL/PDF Features� Robust reporting engine
� Charts
� Bar, Line & Pie
� Barcode Printing
� Use Existing PDF files as Templates
� TrueType Font Embedding
� Encrypted PDF Documents
� Native Support for PNG & JPEG images
� Other types supported via Oracle InterMedia
7
Licensing� Licensed per instance of Oracle
� $600 per instance
� Can download a trial for free
� 5 Page Maximum
� Watermark Appears on all pages
� No additional hardware is required
� PL/PDF installs into the same database as APEX
8
The BLOB!� Result of PL/PDF is nothing more than an Oracle
BLOB
� Thus, you can do anything with PL/PDF output that you can with an Oracle BLOB:
� E-Mail it as an attachment
� Download it to a browser
� Store it in a table
� Index it with Oracle Text
� Schedule a procedure to generate and e-mail PDF files
9
Simple Example
10
plpdf.init;plpdf.NewPage;plpdf.SetPrintFont('Arial',NULL,12);plpdf.PrintCell(50,10,'Hello World');plpdf.SendDoc(l_blob);
Complex Example� eSERT Evaluation Summary Report
11
Layout & Control
12
� All layout is handled via API calls
� There is no GUI tool to design a PL/PDF report
� Seems limiting, and can be at times
� Template feature allows you to use any tool to create the structure of a document and use PL/PDF APIs only to populate the data
� Also, there are APIs that minimize the amount of code required when creating reports
Extras
13
� In addition to its core APIs, PL/PDF offers a number of extra features
� Templates
� Charts
� Bar, Line & Pie
� Bar Codes
� Encryption
� OpenOffice Forms
� TrueType Font Support
Templates
14
� PL/PDF allows you to include a PDF template as a background for any page
� No need to use PL/PDF to create the structure of a document; focus on filling in the data
� Any PDF document can be used
� Easy to create PDF documents from Word, Acrobat, etc.
Templates
15
Charts
16
� Support for three types of charts
� Line
� Bar
� Pie
sumnevaSERT
Settings Summary 28 out of 37 possible points 75.68%Session Duration
0%0 out of 2 possible points
Security60%
6 out of 10 possible points
Application Settings84.62%
11 out of 13 possible points
Authentication Scheme91.67%
11 out of 12 possible points
Security: 4
Application Settings: 2
Session Duration: 2
Authentication Scheme: 1
Exceptions Awaiting Approval
No Data Found
Stale Exceptions
No Data Found
Printed on 19-JUN-2012 08:31 AM by ADMIN Page 5CONFIDENTIAL
Charts
17
Barcodes
18
� Support for a number of types of barcodes:
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
Feline Adult 20/22LB8543
$36.99101262640
P L / P D F T r i a l
Other Features
19
� Ability to encrypt PDF files
� Support for OpenOffice PDF Forms
� LZW compression
� TrueType Font Support
Sweet Spots� PL/PDF is the best solution when:
� The core report definition does not change often
� End Users do not need to create one-off reports
� You have an abundance of PL/SQL resources and little money
20
INSTALLATION
21
Installation Options
22
� PL/PDF is installed by running a series of SQL scripts
� Can use to install on any target OS
� Need to be able to connect to the target database via SQL*Net
� Some additional features may need to be manually installed
� Charts, Bar Codes, etc.
� Installation should take about 15 minutes
Where to Put It� Since PL/PDF is a set of PL/SQL objects, you’ll
need to select a schema to put it in
� Typically use PLPDF, but can name the schema anything
� Best to use its own schema and then create grants & synonyms to access from other schemas
� You’ll need to do this manually
� Start with just PLPDF & PLPDF_TYPE; synonyms for other objects can be added as needed
23
INTEGRATION
24
APEX Integration
25
� Once installed and the corresponding grants are created to your parse as schema, there is NOTHING ADDITIONAL TO CONFIGURE in order to integrate PL/PDF with APEX
� PL/PDF - like APEX - is PL/SQL
� Thus, as long as your parse-as schema can access the PL/PDF objects, that’s all you’ll need
� Seriously.
� There’s nothing else to configure.
� Try it. You’ll see.
APEX Integration� PL/PDF must be called as part of the Page
Rendering process in APEX
� And it must occur before anything else
� Best Practice:
� Create an On Load PL/SQL Process that calls PL/PDF
� Set the Condition to Request = Expression 1
� Add a button/link to that page which sets the Request to trigger the PL/PDF call
26
PL/SQL Package� It’s best to put the logic for a PL/PDF report into
a PL/SQL package
� Centralized
� Can re-use common functions
� More performant
� Easier to work with
� Be sure pass in parameters when possible so that a single package may be called from multiple pages or even outside of APEX
27
PL/SQL Process� A simple PL/SQL Process should be created to
call the report package
� Must be set to fire Before Header and be the first process executed
� Must be condition to only execute when Request = PRINT
� Can be an Application Process
� PL/SQL Code:
28
plpdf_print.print ( p_order_id => :P29_ORDER_ID );
Button
29
� A button can be used to trigger our PDF report
� Redirects to the page where the process is located
� Passes in PRINT to the Request value
Column Link� A Column Link can also be used to print a report
� Redirects to the page where the process is located
� Passes in PRINT to the Request value
� Sets the value of the APEX Item which is passed to the package
30
D E M O N S T R A T I O N
APEX INTEGRATION
31
IMPLEMENTATION
32
Goal
33
� To produce a Sales Receipt for an order generated in the Sample Database Application
� Receipt will encompass a master-detail report
� Single row from the header
� Variable number of rows from the detail
� Should look professional and include a logo
Report Types
34
� PL/PDF can produce two “types” of reports
� Row/Column
� Produce rows & columns of data based on a SQL query
� Forms
� Fill in the data for a form, such as a Tax Form or Job Application
� It’s important to determine which type is needed for a specific requirement up front
� OK to use both in a single report, if needed
Our Example
35
Form ReportBased on a single row of data across one or more tables
Row/Column ReportBased on a SQL Query returning multiple rows of data
Where to Start?
36
� PL/PDF can utilize a PDF document as a template
� Simplifies code greatly, as only the data needs to be printed via the APIs
Eugene BradleySchoephoester RoadWindsor Locks, CT 06906
10/1/13 000003
00001 Business Shirt 1 $50 $50 00003 Trousers 2 $100 $200
$250
12345 Check
The ABCs of the APIs
37
� PL/PDF is nothing more than a set of PL/SQL APIs
� Like any other API set, there’s a learning curve
� Most APIs have default values on most parameters
� Thus you only need to pass values to those you wish to set
� Use param => value notation for best results
� Refer to the documentation for full details
Where to Start� Like any other problem, it all starts with the data
� Analyze the data required and determine the best way to get what you need
� Create views where it makes sense to simplify SQL statements in APEX or PL/SQL
38
DEMO_ORDERS
DEMO_ORDER_ITEMS
DEMO_CUSTOMERS
DEMO_ORDERS� Since we’ll need to reference a row of DEMO_ORDERS, it can be created as a ROWTYPE variable and referenced throughout in the PL/PDF APIs
39
DECLARE l_order_t demo_orders%ROWTYPE;BEGIN
-- Get the Order RowSELECT * INTO l_order_t FROM demo_orders WHERE order_id = p_order_id;
init� Called once to initialize PL/PDF
� Parameters:
� p_orientation
� p_unit
� p_format
40
newPage� Creates a new page
� Called anytime a new page is needed
� PL/PDF will automatically create a new page when needed if data overflows the current page
� Parameters:
� p_orientation
41
Initializing PL/PDF
42
-- Get the TemplateSELECT blob_content INTO l_template_pdf FROM wwv_flow_files WHERE filename = 'sales_receipt.pdf';
l_template := plpdf_parser.getTemplate(l_template_pdf,1);
-- Initialize PL/PDFplpdf.init(p_format => 'letter');l_template_id := plpdf.InsTemplate(l_template);
-- Create a new pageplpdf.NewPage;
-- Place the template on the pageplpdf.useTemplate(l_template_id);
-- Get the TemplateSELECT blob_content INTO l_template_pdf FROM wwv_flow_files WHERE filename = 'sales_receipt.pdf';
l_template := plpdf_parser.getTemplate(l_template_pdf,1);
-- Initialize PL/PDFplpdf.init(p_format => 'letter');l_template_id := plpdf.InsTemplate(l_template);
-- Create a new pageplpdf.NewPage;
-- Place the template on the pageplpdf.useTemplate(l_template_id);
setCurrentXY� Sets the position of the cursor
� Parameters:
� p_x
� p_y
� Similar:
� setCurrentX
� setCurrentY
43
setPrintFont� Sets the font family and style used for text
� Parameters:
� p_family
� p_style
� p_size
44
printCell� Prints a line of text on the page
� Parameters:
45
• p_w
• p_h
• p_txt
• p_border
• p_ln
• p_align
• p_fill
• p_link
• p_clipping
lineBreak� Places the cursor on the next line
� Parameters:
� p_h
46
Printing Customer Details
47
plpdf.SetPrintFont( p_family => 'Courier', p_size => 10);plpdf.setCurrentXY(11,60);
-- Customer DetailsFOR x IN (SELECT * FROM demo_customers WHERE customer_id = l_order_t.customer_id)LOOP plpdf.printCell(70, 10, x.cust_first_name || ' ' || x.cust_last_name, NULL, NULL, 'L'); plpdf.LineBreak(4); plpdf.setCurrentX(11); plpdf.printCell(70, 10, x.cust_street_address1, NULL, NULL, 'L');
Printing Customer Details
48
plpdf.LineBreak(4); plpdf.setCurrentX(11); IF x.cust_street_address2 IS NOT NULL THEN plpdf.printCell(70,10, x.cust_street_address2, NULL, NULL, 'L'); plpdf.LineBreak(4); plpdf.setCurrentX(11); END IF; plpdf.printCell(70, 10, x.cust_city || ',' || x.cust_state || ' ' || x.cust_postal_code, NULL, NULL, 'L');END LOOP;
Other Details
49
-- Date and Order Numberplpdf.setCurrentXY(152,60);plpdf.printCell(26, 10, TO_CHAR(l_order_t.order_timestamp, 'DD-MON-YYYY'),NULL,NULL,'C');plpdf.printCell(30,10,'0000' || p_order_id,NULL,NULL,'C');
-- Payment Methodplpdf.setCurrentXY(10,95);plpdf.printCell(28,10,'n/a' ,NULL,NULL,'C');plpdf.printCell(28,10,'Credit',NULL,NULL,'C');
-- Reset Cursorplpdf.setCurrentXY(10,114);
row_print
50
� ROW_PRINT allows for a lot more flexibility than QUERY_PRINT
� Typically called from inside a loop
� FOR X IN (SELECT * FROM ...)
� DBMS_SQL
� Four different variations are available: ROW_PRINT through ROW_PRINT4
row_print� Sample Parameters
� p_data
� p_width
� p_align
� p_style
� p_maxline
� p_links
� p_h
� p_fill
� p_min_height
� p_clipping
51
Order Lines
52
� ROW_PRINT may or may not suffice for what you need
� Often times just looping through a query and printing the individual columns is just as effective
� Take some time to become familiar with it and what it can and can’t do
Order Lines
53
LOOP plpdf.printCell(29,10,'0000' || x.product_id ,NULL,NULL,'C'); plpdf.printCell(84,10,x.product_name, NULL,NULL,'L'); plpdf.printCell(28,10,x.quantity, NULL,NULL,'C'); plpdf.printCell(28,10,TO_CHAR(x.list_price, 'FML999G999G999G999G990D00'), NULL,NULL,'R'); plpdf.printCell(28,10,TO_CHAR(x.list_price * x.quantity,'FML999G999G999G999G990D00'), NULL,NULL,'R'); plpdf.LineBreak(4);END LOOP;
sendDoc� Returns the PDF document to a BLOB variable
� Parameters:
� p_blob
54
Download File API� You can also create a single procedure to handle
file downloads
� Pass in the BLOB and filename
� All PL/PDF reports can call this procedure
� In fact, it is recommended that PL/PDF reports be based on a package
� Reusability
� Security
55
Printing the PDF
56
-- Send the contents of the PDF document to l_blob and Print itplpdf.SendDoc(l_blob);
-- Send the PDF document to the browserowa_util.mime_header('application/pdf', FALSE);htp.p('Content-Disposition: inline; filename=' || p_filename || '.pdf') ;htp.p('Content-Length: ' || dbms_lob.getlength(l_blob)) ;owa_util.http_header_close;wpg_docload.download_file(l_blob);apex_application.g_unrecoverable_error := TRUE;
Table of Contents
57
� PL/PDF allows you to automatically crete a Table of Contents
� You can add “bookmarks” throughout your application that link back to the main table of contents
� Fully automated; no need to calculate anything
SECURITY
58
PL/PDF Security
59
� Since PL/PDF is all PL/SQL, there are no specific provisions when it comes to security
� Any database layer security will work
� Secure Views
� Label Security
� VPD
VPD Function
60
CREATE OR REPLACE FUNCTION plpdf_vpd (p_schema IN VARCHAR2 DEFAULT NULL, p_object IN VARCHAR2 DEFAULT NULL)RETURN VARCHAR2ASBEGIN
RETURN q'!user_name = '!' || v('APP_USER') || q'!'!';
END;/
Enabling VPD
61
BEGINDBMS_RLS.add_policy (object_schema => 'PLPDF_OOW', object_name => 'DEMO_ORDERS', policy_name => 'DEMO_ORDERS_VPD', function_schema => 'PLPDF_OOW', policy_function => 'PLPDF_VPD', statement_types => 'SELECT');END;/
Disabling VPD
62
BEGINDBMS_RLS.drop_policy (object_schema => 'PLPDF_OOW', object_name => 'DEMO_ORDERS', policy_name => 'DEMO_ORDERS_VPD');END;/
D E M O N S T R A T I O N
VPD & PL/PDF
63
SUMMARY
64
PL/PDF Report Card
65
Installation
Integration
Implementation & Ease of Use
Security
Cost
AADAA
Summary
66
� PL/PDF provides a robust, cost effective solution for producing high quality PDF documents from any APEX application
� Not always the right tool for every job; but in many cases, it works quite well
� Low cost and zero footprint means that it should at least be seriously considered
http://www.odtug.com
67