Link to home
Start Free TrialLog in
Avatar of madpuppy
madpuppyFlag for United States of America

asked on

save a PDF file submitted from adobe reader to cfm

I am trying to save a PDF file (which I am being passed from a adobe pdf submit service as I think a binary stream) in a browser, I just want the PDF to saved so I can attach it and email it.   What CFM should I use to retrieve the submitted pdf content in a binary and retain a  valid pdf file ?- I found the below code here as one answer but it is not doing binary stuff.  The problem I am having is that the pdf that I reconstruct is .close. looking but not valid; I think I see it is losing carriage returns or something it is not good please point me an the correct binary in statements...

I think I need to do what this person did but with CFM
https://www.experts-exchange.com/questions/21102554/Response-ContentType-application-pdf.html


<cfscript>
pc = GetPageContext();
req = pc.getRequest();
readerObj = req.getReader();

output = '';
line = readerObj.readLine();
while (isDefined("line")) {
        output = output & line;
        line = readerObj.readLine();
}
readerObj.close();
</cfscript>
<cfoutput>#output#
</cfoutput>

I also tried this but the content was empty?.....content [empty string]

<cfset x = GetHttpRequestData()>
<cfoutput><hr><cfdump var="#x#"><br></cfoutput>


struct
content [empty string]  
headers struct
ACCEPT image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/x-shockwave-flash, application/msword, application/vnd.ms-excel, */*  
ACCEPT-ENCODING gzip, deflate  
ACCEPT-LANGUAGE en-us  
CACHE-CONTROL no-cache  
CONNECTION Keep-Alive  
CONTENT-LENGTH 158289  
CONTENT-TYPE application/pdf  
COOKIE CFID=129137; CFTOKEN=45168361; SC_ID=; TOMANYATTEMPTMSG=  
USER-AGENT Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)  
 
method POST  
protocol HTTP/1.1  


Avatar of slushe
slushe

If I understand correctly, you want to catch an incoming binary stream into a PDF file.

This is very similar to when you want to store binary files in a mySql database (images, video, etc) field such as a BLOB, and then read it out and create a file out of it, except in reverse.

You will definitely have to use the cfcontent command.  Google "cfcontent examples" without the quotes to see the different ways of implementing:  I've included a few below, I think you'll know what you're looking for right away if you're already doing something this far out ;)



- - -

Example :

Returning MIME Content Types with Cold Fusion <CFCONTENT>

The <CFCONTENT> tag has two attributes. The mandatory TYPE attribute specifies which MIME Content Type is being returned by the current template. The optional FILE attribute dynamically inserts a file from the Web server into the output stream.

The following example demonstrates the use of <CFCONTENT> to output the image of an employee where the path to the image (i.e. C:\images\steve.jpeg) is stored in the field employees.photo:

<CFQUERY NAME="GetEmployeeImageFile" DATASOURCE="A2Zbooks">
     SELECT photo FROM employees
     WHERE employees.employeeid=#URL.employeeid#
</CFQUERY>
<CFCONTENT TYPE="image/jpeg" FILE="#GetEmployeeImageFile.photo#">


- - -

CF DOCS shows: http://www.edgewebhosting.net/cfdocs/CFML_Language_Reference/2_ColdFusion_Tags/lr2_022.htm

that the cfcontent type tag is to set what kind of data is being returned.  Concievably, you should be able to pipe it inbound just as easily.

- - -

http://www.mail-archive.com/cf-list@kcfusion.org/msg01540.html seems to have a good dialogue too that might be helpful

Hope that helps,
s
Avatar of madpuppy

ASKER

Well I guess I could look at blob processing and see if it is the same it is kinda like fetching a pdf from a blob, I have done all that before in a query except it the pdf stream is arriving from  a post from a submit button that is sent from the inside of a pdf form when you set up a pdf form button you can have it submit the whold pdf to the url, I have no other control over the post.  This code works but the file it builds is no longer a good pdf file becasue of the line by line processing ruins the pdf comming in.

<cfscript>
pc = GetPageContext();
req = pc.getRequest();
readerObj = req.getReader();

output = '';
line = readerObj.readLine();
while (isDefined("line")) {
        output = output & line;
        line = readerObj.readLine();
}
readerObj.close();
</cfscript>
<cfoutput>#output#
</cfoutput>

In any case I have given up on this and now I am submitting the form as html and builidng a fdf from the submit and now merging this on the server to a new flattened pdf and emailing that pdf back. I seems to work fine. but still it would nice to know how to get the content correctly I will try putting in into CFCONTENT with like a readerObj.readAll();  I am  not very good at java io servlet command stuff

 
I will be gone for a few days but I would love to see if anyone has a good command for getting the
readerObj content  into a var for processing...
Yeah, as I thought about it over the day (done a lot of PDF/cf stuff last few months), you could treat the variable of what the post returns via cfhttp (or using the code you already have in cfscript) like you would a blob variable.  Just set the variable type, and then pipe the stream into a file.

I'd probably use something a bit more robust than cfhttp.  I like cfhttp5 a lot, it does multithreaded requests and doesn't bog down. Concievably, using something like that, you could take the returned byte stream from the POST, pipe it straight into a variable, throw the cfcontent declaration on it, and save it to a file, or a db if you so chose.  Nice way to pull a lot of pdfs off a site, or automatically store a pdf that is generated for you.

If you're away for a few days -- I'll be looking at this PDF stuff this weekend for another project I'm working on, I'll post anything more that would help towards a proof of concept.  This should work without any pitfalls, as CF generally excels in this kind of stuff.
now I guess the question more defined is how to pipe the raw stream out from java.io  req.getReader(); and into that blob var using cfcontent or  cfhttp....not using readline() cause it messes it up, my work around seems cheesy but works.
is there a reason you can't dump the req.getReader straight into a variable in cf, set the cfcontent type, and then write the field out to a file so the integrity is maintained.

If you could share the pdf outputter, I wouldn't mind trying it out just to make it work..

I tried that using cfcontent  with type = application/pdf and it was not working for me, what is the best way to share the pdf putputter ? it is just a test "coffee survey" document made as a simple pdf form with sampling of a type in text, radio and checkbox then a button that submits/mouse up posts action to a website url and cfm file indicated with the full pdf option radio checked. You would have to change the url and work your own .cfm to work this. the cfm you saw from what I posted above but the output is not a valid pdf anymore. let me know thank you!
Avatar of CEHJ
You posted a pointer to this in the Java TA. Not familiar with CF, but do i take it that you can include Java code?
Well for the moment, i'll assume that the answer to that is yes, as i don't want to have to save the example i've just written ;-) You can't use a Reader, as a pdf file is 'binary' and character decoding will trash the file.

InputStream in = request.getInputStream();
final int BUF_SIZE = 1 << 10 << 3; // 8k buffer
byte[] buffer = new byte[BUF_SIZE];
int bytesRead = 0;
FileOutputStream out = new FileOutputStream("x.pdf");
while ((bytesRead = in.read(buffer)) > -1) {
      out.write(buffer, 0, bytesRead);
}
in.close();
out.close();
Nope I do not think I can write NATIVE java but I do think you are getting me closer getting me away from readerObj thanks.. I looked around and I think I can do some things like these examples...

http://cephas.net/blog/2003/06/

http://www.houseoffusion.com/cf_lists/index.cfm?method=messages&threadid=24306&forumid=4

below is what I tried,  but again i am in deep unfamiliar water this is what I tried and I got errors only..

<cfscript>
pc = GetPageContext();
req = pc.getRequest();
inputsr  = req.getInputStream();

// get a BufferedReader object
input = CreateObject("java", "java.io.BufferedReader");

// call the BufferedReader constructor
input.init(inputsr);


output = '';
// loop over result by reading line by line
run = true;
while (run) {
   // read the result line by line
   resultLine = input.readLine();
   if (len(resultLine) GT 0) {
      output = output & resultLine;
   } else {
      run = false;
   }
}  

</cfscript>

I am not at all sure that this inputsr  = req.getInputStream();
is a valid command...

I found this page on what I can do with JAVA and CFML but this is hurting my SQL brain - I need an expert !


http://livedocs.macromedia.com/coldfusion/6/Developing_ColdFusion_MX_Applications_with_CFML/Java5.htm#1160838
Buffer it using a BufferedReader and then output it all at once
As i mentioned earlier, Java Readers should *not* be used. I'm not familiar with CF/Java interaction, but wrapping the code i gave you in a simple bean-like Java class will probably be easiest
ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
AH :) sorry, didnt see you comment about readers
Ok No readers! granted that your code would work if I complie , get the server admin to put it where it should go and then  call it using cfobject setting the file to go to... but OHGAWD I hate to be difficult, but how can this be so much effort to get a post that you already have already in  GetPageContext();  out to a file ...This seems a bit over the top of something so basic like this. I might as well just do the fdf merge up on the server as it has less data traffic. I would have thought that someone else had tired this before and had a simple answer, one that did not require compiles and moving file to places that I do not have permission.  I also have GetPageContext.forward and .include available in cf.  Oh well, I will wait a bit and see if any other more CF based or script solutions arrive but if not then give it to you as it is an answer just not a simple snippet of script one I was expecting. :,(
I'd be surprised too if there's no component you can use already. Have a look at this for instance:

http://www.devarticles.com/c/a/Cold-Fusion/Multiple-File-Upload-with-CFFILE/