NetTalk Central

Author Topic: PDF Documents in BLOB, Part 2  (Read 11052 times)

jking

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • Email
PDF Documents in BLOB, Part 2
« on: April 27, 2012, 12:58:22 PM »
     I have part 1 of this project working, where I have PDF documents uploaded and stored in a BLOB.  Now I want to be able to view the contents of the BLOB.  My plan is to place a button at the end of each record in a browse, that when clicked, allows the user to view the PDF in the BLOB in a new browser window.  From here they may save the pdf file or print it.
     I have looked at example apps 26 and 40, as well as searched NetTalk Central for BLOB and sendfile articles.  Here is my plan:

1.  The button on the browse list calls p_web._SendFile(p_filename).  The parameter p_filename will be filled with the actual filename of the pdf which is stored in a field of my file called XOFTCRF.  For example, it may contain ABC.pdf.

2.  My file XOFTCRF, has a unique ID called CRFID.  The key on this field will be used to get the record currently selected in the browse, where needed.

3.  Example 40 contains code in the _sendfile method of the WebHandler procedure.  This allows the contents of the BLOB to be sent directly to the browser without first writing the file to disk.  I'll modify this code to use my file, XOFTCRF, and get the BLOB contents of the currently selected record.

4.  Assuming this is all correct, the browser should display the PDF contents (ABC.pdf) of the selected record, with the capability to save or print the PDF.

5.  I should not need to create a NetWebPage with a Page Type set as File/PDF.

     I have not tried this yet as I wanted to be sure I understood the basics first.  Does this seem like a viable plan?

Thanks,

Jeff


jking

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • Email
Re: PDF Documents in BLOB, Part 2
« Reply #1 on: April 27, 2012, 07:05:46 PM »
     Ok, I thought I would give this a try and added the following code:

In the _sendfile embed of the WebHandler I have the following:

p_web.ReplyContentType = 'application/pdf'

Access:XOFTCRF.Open()
Access:XOFTCRF.UseFile()
CRF:CRF_File_Name = 'web\' & sub(p_FileName,len(clip(self.site.WebFolderPath)) + 2,255)
if CRF:CRF_File_Name[1] = '/' then CRF:CRF_File_Name = sub(CRF:CRF_File_Name,2,255).
loop x = 1 to len(clip(CRF:CRF_File_Name))
  if CRF:CRF_File_Name
  • = '/' then CRF:CRF_File_Name = '\'.

end

CRF:CRF_ID = p_web.GSV('CRF:CRF_ID')
If Access:XOFTCRF.Fetch(CRF:CRFID_key) = 0
  loc:found = CRF:CRF_File{prop:size}
  sendstring &= new(string(loc:found))
  sendstring = CRF:CRF_File[1: loc:found]
  ! allows the browser to cache this file.
  self.ForceNoCache = 0
  self.HeaderDetails.CacheControl = ''
  self.FileDate = today() - 200
  self.FileTime = 6000 !clock()
  ! end of cache settings
  self._SendMemory(sendString,loc:found)
  dispose(sendString)
End
Access:XOFTCRF.Close()
If loc:found then return.

Then, in the button I added to the browse as type other, I added the following in the "user pressed button" embed:

p_web._SendFile(p_web.GSV('CRF:CRF_File_Name'))


     Everything compiles fine.  When I open the browse and press the button, nothing appears to happen.  However, something is happening as I can no longer click on cancel or save, it appears to hang.  I have used topspeed scan to look at the contents of the XOFTCRF file and there appears to be PDF content in the BLOB.
     I would be glad to send a copy of this app but I would need to remove some templates that I use for BLOBs, and turn off SSL.  I'm on NT 6.27.

Any ideas where I went wrong?

Thanks,

Jeff

Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11302
    • View Profile
Re: PDF Documents in BLOB, Part 2
« Reply #2 on: April 27, 2012, 08:51:58 PM »
I think an example would be best.
Perhaps you don't have to tweak your app as much as just make a simple example showing the effect you are getting - you can prime it with a data file that contains some PDF's already.

cheers
Bruce

jking

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • Email
Re: PDF Documents in BLOB, Part 2
« Reply #3 on: April 27, 2012, 09:01:29 PM »
Bruce,

     I'll put together a test app and send it along shortly.  In the meantime, I noticed another method called _sendBlob which takes just a filename as its parameter.  Is this a working method and would it be better to use this instead of _sendFile?

Thanks,

Jeff

jking

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • Email
Re: PDF Documents in BLOB, Part 2
« Reply #4 on: April 27, 2012, 10:42:45 PM »
Bruce,

     Attached is an example app, compiled as an exe.  I normally compile as a dll and use the Multi-Host app with an SSL certificate.  What I'm trying to accomplish is to allow the users to click on a button at the end of each record in the XOFTCRF browse and view the PDF stored in the BLOB.  I don't want to have to create the pdf file first if possible, thus I'm using modified code from the _SendFile embed of example 40.
     To get to the CRF browse, open the Study Patient browse from the main menu.  Click on change and then go to the CRF tab.  Here you will find the browse listing the PDF's.  I want to click on the button at the end of each record and send the PDF to the browser for viewing or printing.
     I have commented out some code since we are not creating any files.  Hopefully you can show me where the problem is.

Thanks,

Jeff

[attachment deleted by admin]

jking

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • Email
Re: PDF Documents in BLOB, Part 2
« Reply #5 on: April 28, 2012, 08:31:43 PM »
Bruce,

     I have made a bit of progress with this.  However, it is a bit strange.  I find I can only get the PDF contents of the BLOB to download if I do the following:

     Open the web app, go to Browse, Study Patients, click on change to open the dummy patient.  Next go to the CRF tab and click on change to open the record.  Here is where it gets strange.  If you now click on Cancel or Save, then the SendFile code fires and asks me to open or save the blob contents.  It contiually does this and I must force the form to close.  
     So I have verified the blob contents are valid PDF documents, and the code to get the blob works.  Now I just need to get the sendfile to fire only when I click the button at the end of each record in the browse.

     Here is the code I currently have in the sendfile embed:

Access:XOFTCRF.Open()
Access:XOFTCRF.UseFile()

CRF:CRF_ID = p_web.GSV('CRF:CRF_ID')
p_web.HeaderDetails.ContentDisposition = 'attachment; filename="'&p_web.GSV('CRF:CRF_File_Name')&'"'
If Access:XOFTCRF.Fetch(CRF:CRFID_key) = 0
  loc:found = CRF:CRF_File{prop:size}  !blob size
  sendstring &= new(string(loc:found))
  sendstring = CRF:CRF_File[0: loc:found]
  ! allows the browser to cache this file.
  !self.ForceNoCache = 0
  !self.HeaderDetails.CacheControl = ''
  !self.FileDate = today() - 200
  !self.FileTime = 6000 !clock()
  ! end of cache settings
  self._SendMemory(sendString,loc:found)
  dispose(sendString)
End

Access:XOFTCRF.Close()

If loc:found then return.




Thanks,

Jeff
« Last Edit: April 28, 2012, 08:34:46 PM by jking »

kevin plummer

  • Hero Member
  • *****
  • Posts: 1195
    • View Profile
    • Production Accounting and Software Payroll
Re: PDF Documents in BLOB, Part 2
« Reply #6 on: April 29, 2012, 05:07:29 PM »
Hi Jeff,

I would be inclined to move your logic out of the _sendfile method and add it to servedocument net web file. You can copy the source file from the download files example. So on your button add the servedocument URL with a couple of parameters so you know what table, recordid blob etc you wish to serve.

I use this method to serve up created reports, Excel docs, HTML and docs from disk etc and all my logic sits in this one file.

Just a thought!

Cheers,

Kevin

kingja

  • Sr. Member
  • ****
  • Posts: 261
    • View Profile
    • Email
Re: PDF Documents in BLOB, Part 2
« Reply #7 on: April 29, 2012, 06:24:44 PM »
Kevin,

     Would I still be able to serve up documents from the blob?  I don't really want to write files to disk first.  Also, could you provide a short example of how to pass the table and blob I'd, etc.?

Thanks,

Jeff

kevin plummer

  • Hero Member
  • *****
  • Posts: 1195
    • View Profile
    • Production Accounting and Software Payroll
Re: PDF Documents in BLOB, Part 2
« Reply #8 on: April 29, 2012, 08:37:14 PM »
In that case and after a quick look at "the book" yes you probably need to move the blob code back. However, I would still call the servedocument procedure.

To call a URL with parameters it is something like 'servedocument?TableName=' & p_web.gsv('TableName') & '&RecordID=' & p_web.gsv('RecordID')

I think the problem with the code you posted in the _sendfile embed (unless you didn't post everything) is that every time _sendfile is called (and it is called every time you do something) the code will fire if  p_web.GSV('CRF:CRF_ID') has a value. So you would need to make sure you set p_web.GSV('CRF:CRF_ID') back to 0 after this code runs.

Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11302
    • View Profile
Re: PDF Documents in BLOB, Part 2
« Reply #9 on: April 29, 2012, 09:59:53 PM »
Hi Jeff,

before I look at your example, perhaps you want to follow Kevin's suggestion a bit. See example "File Download" for an example of a "serveDocument" procedure that takes parameters.

Cheers
Bruce

jking

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • Email
Re: PDF Documents in BLOB, Part 2
« Reply #10 on: April 30, 2012, 09:16:54 AM »
Bruce,

     I took Kevin's advice about setting 'CRF:CRF_ID' back to zero.  Actually, since this ID is used to filter the child browse, I did not think it a good idea to change this.  So I created a new session variable called 'myCSFID'.  I set this to zero at the beginning of the browse procedure, then again at the end of the sendfile code.  In the 'user pressed button' embed, I set myCRFID = p_web.GSV('CFR:CFR_ID'), the ID of the currently selected record.  I modified the sendfile code to use this new session variable as follows:

If p_web.GSV('myCRFID') <> 0    !

  Access:XOFTCRF.Open()
  Access:XOFTCRF.UseFile()

  CRF:CRF_ID = p_web.GSV('myCRFID')
  p_web.HeaderDetails.ContentDisposition = 'attachment; filename="'&p_web.GSV('CRF:CRF_File_Name')&'"'
 
  If Access:XOFTCRF.Fetch(CRF:CRFID_key) = 0
    loc:found = CRF:CRF_File{prop:size}  !blob size
    sendstring &= new(string(loc:found))
    sendstring = CRF:CRF_File[0: loc:found]
    self._SendMemory(sendString,loc:found)
    dispose(sendString)
  End

  Access:XOFTCRF.Close()
       
  If loc:found then return.

  p_web.SSV('myCRFID', 0)

End!If
p_web.SSV('myCRFID', 0)


     Now, the blob code in the sendfile embed does not appear to fire unless there is a value in the myCRFID session variable.  I believe this is the result expected as Kevin indicated in his post.  However, I still don't get the blob code to send the blob contents to the browser.  Can you take a look at the example and see if you can help?

Thanks,

Jeff

kevin plummer

  • Hero Member
  • *****
  • Posts: 1195
    • View Profile
    • Production Accounting and Software Payroll
Re: PDF Documents in BLOB, Part 2
« Reply #11 on: April 30, 2012, 03:08:02 PM »
Hi Jeff,

The logic from my reading of the book is that your button has a URL with a filename to serve. Within the _sendfile method you first check the blob for the file and if so extract that file and serve it up. If you have a URL on a button then any ss code on that button does not fire. So you need to have something in the URL so you know when to run your blob code. I think I would just try to get it working within the servedocument procedure like example 40 by first extracting the file to disk. Once that works then I think you can move some logic to the _sendfile method.

HTH's

Kev

jking

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • Email
Solved - Re: PDF Documents in BLOB, Part 2
« Reply #12 on: April 30, 2012, 05:44:27 PM »
Bruce and Kevin,

     I think I have the solution to this.  I removed the BLOB code from the _sendfile embed and placed it in the processed code embed of the ServeDocument procedure.  This procedure is set page type OTHER.  I then pass the CRF_ID and CRF_File_Name as parameters to this procedure.  Here is the final code:

  Access:XOFTCRF.Open()
  Access:XOFTCRF.UseFile()

  CRF:CRF_ID = p_web.GetValue('myCRFID')
  p_web.ReplyContentType = 'application/pdf' 
  p_web.HeaderDetails.ContentDisposition = 'attachment; filename="'&p_web.GetValue('myCRFFile')&'"'
 
  If Access:XOFTCRF.Fetch(CRF:CRFID_key) = 0
    loc:found = CRF:CRF_File{prop:size}  !blob size
    sendstring &= new(string(loc:found))
    sendstring = CRF:CRF_File[0: loc:found]
     p_web._SendMemory(sendString,loc:found)
    dispose(sendString)
  End

  Access:XOFTCRF.Close()
   
  If loc:found then return.

I still have some clean-up to do but it is working.  Let me know if you think there are any potential problems with this method.  Thanks to both of you for helping with this.

Jeff