I'd like to be able to output a pdf in browser (which is all fine and dandy) but limit the number of pages shown. Ie. the reader can see the content of what's he's trying to buy is accurate but at the same time I`m not handing the file for free. I can batch edit the files to create new 3-5 paged pdf's for my purpose, but that's a hassle and I'd also have to upload the 'landing page' pdf's to the server, keeping in mind the category of the product and whatnot.
A simplified version of what I'm asking,
user -> download link -> pdf opens with the first 5 pages -> adds a 'buy now' on the 6th pdf page;
I am happy to do this through a third-party script. The only thing required would be for the user to not be able to access the entire pdf doc (like if the trigger-link would be <a href="link.tld/name" id="trigger"> the user shouldn`t be able to fetch the url of the full-doc.
You can actually do it by adding another copy of the pdf file on your webserver and using tcpdf php class, you can actually restrict pages, by deleting remaining pages.
require_once('tcpdf_include.php');
$pdf->deletePage(6,100);//Deletes pages from 6-100
You can have a good read about the complete tcpdf here
This is my choice for any pdf handlers on my site.
The only possible way I think is to create another copy of PDF and it will have only first five pages only...and then from 6th page the message will be there to Buy this Book ans How to Buy and what is amount etc.....
So , just create another preview like version
Thanks again to #user2768665 for the best answer to my troubles. This is my gameplan:
Since I have the files named as in the link, I first grab the WP link of the product using GET, then store that in a variable, preg_replace it to erase the rest of the link (with regex), store that result in a new var, let's say $link2p .
Then I add the call to the product (Download) to open up the processing php script, use tcpdf (user2768665's answer) to delete anything that goes after page 5, add the page with the company's logo as being page 6, and at the end of it add the
Click <a href="http://domain.ltd/saleProcessPage/<?php echo $link2p;?>"here</a> to download <?php echo $link2p;?> FULL PDF
Or, in my case (since I have the a 3rd party paying platform -and you might have the same-), we first run a database check on the product(based on its name) to retrieve the link to our product in our paying platform and then we do the same as above.
Then, we modify the the original's pdf name and output it differently;
$pdf->Output($link2p.'.pdf', 'Insert w/e random string generator.pdf');
It's a great solution as it keeps original pdf files out of any "Inspect Element" user, it runs in the backend and hey, random name si given out.
// Other things I`m thinking about:
Since I haven't read the full documentation for tcpdf, can't be sure on this but I haven't seen any page count ability (which is needed in order to do this fully automatically for the files: i.e. $pdf->deletePage(6,100); becomes $pdf->deletePage(6,endofpdf); For that purpose, I add what I've read before placing the question : Count the number of pages in a PDF in only PHP . So we store that into a $count variable (to see how many files the pdf has) so that we can use $pdf->deletePage(6,$count); Again, haven't read the tcpdf full documentation, so this may be useless.
I'm going to do a full code workup on this after I get some sleep and post the example in its final form. Hopefully this will help others stuck in the same place.
A great thank you again to #user2768665 and #Monts_mind_hacker for the interest in the topic. Awesome guys.
You can use FPDI to create a preview of the first 5 pages:
$pdf = new FPDI();
$pageCount = $pdf->setSoruceFile('your.pdf');
$pageCount = min($pageCount, 5);
for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
$tplIdx = $pdf->importPage($pageNo);
$s = $this->getTemplatesize($tplIdx);
$this->AddPage($s['w'] > $s['h'] ? 'L' : 'P', array($s['w'], $s['h']));
$this->useTemplate($tplIdx);
}
$pdf->AddPage();
// add the link to the shopping cart on the last page...
$pdf->Output('5-pages.pdf', 'D');
Related
I am attempting to create a Click Here link in my report and have it open an image (file) in a new tab instead of replacing the report page in the browser.
=Fields!ManufacturerDataPlatePhoto.Value
(Returns
file://cld-sql-01/1234/Web_live_FileUploads/iOS%20Applications/MyAssets/images/Live/20%20May%202019/asset70-13-RES8743.jpg)
This returns the image correctly, but on the same page as the report so the user would have to click back in her browser and rerun the report.
="javascript:void(window.open('file:///" & Fields!ManufacturerDataPlatePhoto.Value & "','_blank'))"
(Returns
file://cld-sql-01%5C1234%5CSEG_Web_live_FileUploads%5CiOS%20Applications%5CMyAssets%5Cimages%5CLive%5C20%20May%202019%5Casset70-13-RES8743.jpg)
Opens a new tab, but with a broken link, because the forward slashes have been replaced with %5C.
Any ideas how I could put the forward slashes back in?
You need to do URL Encoding for your url, there's a good article that discuss the details on how you can do it in SSRS, here's the link
Ultimately any solution with JavaScript or VB Functions became too difficult because of all the ways different browsers and their versions display (or completely block) network file paths access.
It was necessary in the end to simply add a thumbnail image in the report using the image path I pulled from the DB and a note below the image to "Right-Click then Save Image".
This also provided an elegant way to provide the image automatically in Excel, Word, etc, and providing the path in the ToolTip added additional functionality to the report the client hadn't thought of as well.
Thank you Tholitz_Reloaded for your answer, I'm sorry I cannot upvote you now, but I do not have >15 reputation yet on this account yet.
Final solution results
I am working on a quite big eWeb tool which includes lots of .js & .php files and this tool is developed by someone else that I can not reach.
Assume that a customer buys some stuff and at the end, as a seller, I am supposed to confirm the customer's shopping by clicking the 'confirm order' button in some table. Now, I want to print a PDF file (which is either located in my local disk or on the server of the eWeb tool depends on the difficulty) when I click the confirm button. I can reach the printer and print the PDF file by following PHP code in my localhost when I directly call it:
<?php
$printer ="HP Officejet Pro X476dw MFP PCL 6 (Network)";
$path = "C:/Test_PDF/TestPDF.pdf";
$fileName = "TestPDF.pdf";`
if($ph = printer_open($printer)) {
$filecontents = file_get_contents($path);
printer_set_option($ph, PRINTER_MODE, "RAW");
printer_write($ph, $filecontents);
printer_close($ph);
}
?>
Now, what I want is to print the PDF file also from the web tool when I click the 'confirm order' button! I do not want to load the PDF file in a hidden iframe or embed it somewhere because, as I said before, the tool is quite big and I do not want to cause any problem somewhere else for now.
Can anybody give me some ideas about the solutions please?
Assuming that PHP is a server-side language, as some people said before, you can't send a print request to a client. The request is originated in the server, so...
What you can do:
1.- Load the pdf in the webpage.
2.- Handle the body onLoad as follows:
<body onload="window.print();">
That way the client will use it's printer if any.
I know that you don't want to load the pdf in a webpage but... This seems like the only solution.
P.D.: I'm not sure if you want to print the receipt for the customer or the seller. Explain yourself better and I will try to help you :)
in my webpage you can read book in pdf format. The problem is that some books have around 1000 pages and the PDF is really big so even if the user reads just 10 pages the server download the full pdf, so this is awful for my hosting account because I have a transfer limit.
What could I do to display the pdf without load the full PDF.
I use pdf.js
Greetings.
ORIGINAL POST:
PDF files are designed in a way that forces the client side to download the whole file just to get the first page.
The last line of the PDF file tells the PDF reader where the root dictionary for the PDF file is located (the root dictionary tells the reader about the page catalog - order of pages - and other data used by the reader).
So, as you can see, the limitations of the PDF design require that you use a server side solution that will create a new PDF with only the page(s) you want to display.
The best solution (in my opinion) is to create a "reader" page (as opposed to a download page) that requests a specific page from the server and allows the user to advance page by page (using AJAX).
The server will need to create a new PDF (file or stream) that contains only the requested page and return it to the reader.
if you are running your server with Ruby (ruby on rails), you can use the combine_pdf gem to load the pdf and send just one page...
You can define a controller method that will look something like this:
def get_page
# read the book
book = CombinePDF.parse IO.read("book.pdf")
# create empty PDF
pdf_with_one_page = CombinePDF.new
# add the page you want
# notice that the pages array is indexed from 0,
# so an adjustment to user input is needed...
pdf_with_one_page << book.pages[ params[:page_number] - 1 ]
# no need to create a file, just stream the data to the client.
send_data pdf_with_one_page.to_pdf, type: 'application/pdf', disposition: 'inline'
end
if you are running PHP or node.js, you will need to find a different server-side solution.
Good luck!
EDIT:
I was looking over the PDF.js project (which looks very nice) and notice the limited support statement for Safari:
"Safari (desktop and mobile) lacks a number of features or has defects, e.g. in typed arrays or HTTP range requests"...
I understand from this statement that on some browsers you can manage a client-side solution based on the HTTP Byte Serving protocol.
This will NOT work with all browsers, but it will keep you from having to use a server-side solution.
I couldn't find the documentation for the PDF.js feature (maybe it defaults to ranges and you just need to set the range...?), but I would go with a server-side solution that I know to work on all browsers.
EDIT 2:
Ignore Edit 1, as iPDFdev pointed out (thank you iPDFdev), this requires a special layout of the PDF file and will not resolve the issue of the browser downloading the whole file.
You can take following approach governed by functionality
Add configuration (i.e. kind of flag) whether you want to display entire PDF or not.
While rendering your response read above mentioned configuration if flag is set generate minimal PDF with 20 pages with hyperlink to download entire PDF else minimal PDF with 20 pages only
When you prepare initial response of your web page add PDF which contains say 20 pages (minimal PDF) only and process the response
So I've been researching this for a couple days and haven't come up with anything conclusive. I'm trying to create a (very) rudimentary liveblogging setup because I don't want to pay for something like CoverItLive. My process is: Local HTML file > Cloud storage (Dropbox/Drive/etc) > iframe on content page. All that works, and with some CSS even looks pretty nice despite the less-than-awesome approach. But here's the thing: the liveblog itself is made up of an HTML table, and I have to manually copy/paste the code for a new row, fill in the timestamp, write the new message, and save the document (which then syncs with the cloud and shows up in the iframe). To simplify the process I've made another HTML file which I intend to run locally and use to add entries to the table automatically. At the moment it's just a bunch of input boxes and some javascript to automate the timestamp and write the table row from the input data.
Code, as it stands now: http://jsfiddle.net/LukeLC/999bH/
What I'm looking to do from here is find a way to somehow export the generated table data to another .html file on my hard drive. So far I've managed to get this code...
if(document.documentElement && document.documentElement.innerHTML){
var a=document.getElementById("tblive").innerHTML;
a=a.replace(/</g,'<');
var w=window.open();
w.document.open();
w.document.write('<pre><tblive>\n'+a+'\n</tblive></pre>');
w.document.close();
}
}
...to open just the generated table code in a new window, and sure, I can save the source from there, but the whole point is to eliminate steps like that from the process.
How can I tell the page to save the generated code to a separate .html file when I click on the 'submit' button? Again, all of this happens locally, not on a server.
I'm not very good with javascript--and maybe a different language will be necessary--but any help is much appreciated.
I suppose you could do something like this:
var myHTMLDoc = "<html><head><title>mydoc</title></head><body>This is a test page</body></html>";
var uri = "data:application/octet-stream;base64,"+btoa(myHTMLDoc);
document.location = uri;
BTW, btoa might not be cross-browser, I think modern browsers all have it, but older versions of IE don't. AFAIK base64 isn't even needed. you might be able to get away with
var uri = "data:application/octet-stream,"+myHTMLDoc;
Drawbacks with this is that you can't set the filename when it gets saved
You cant do this with javascript but you can have a HTML5 link to open save dialogue:
<a href="pageToDownload.html" download>Download</a>
You could add some smarts to automate it on the processed page after the POST.
fiddle : http://jsfiddle.net/ghQ9M/
Simple answer, you can't.
JavaScript is restricted to perform such operations due to security reasons.
The best way to accomplish that, would be, to call a server page that would write
the new file on the server. Then from javascript perform a POST request to the
server page passing the data you want to write to the new file.
If you want the user to save the page to it's file system, this is a different
problem and the best approach to accomplish that, would be to, notify the user/ask him
to save the page, that page could be your new window like you are doing w.open().
Let me do some demonstration for you:
//assuming you know jquery or are willing to use it :)
var html = $("#tblive").html().replace(/</g, '<');
//generating your download button
$.post('generate_page.php', { content: html })
.done(function( data ) {
var filename = data;
//inject some html to allow user to navigate to the new page (example)
$('#tblive').parent().append(
'Check your Dynamic Page!');
// you data here, is the response from the server so you can return
// your new dynamic page file name here.
// and maybe to some window.location="new page";
});
On the server side, something like this:
<?php
if($_REQUEST["content"]){
$pagename = uniqid("page_", true) . '.html';
file_put_contents($pagename, $_REQUEST["content"]);
echo $pagename;
}
?>
Some notes, I haven't tested the example, but it works in theory.
I assume that with this the effort to implement it should be minimal, assuming this solves your problem.
A server based solution:
You'll need to set up a server (or your PC) to serve your HTML page with headers that tell your browser to download the page instead of processing the HTML markup. If you want to do this on your local machine, you can use software such as WAMP (or MAMP for Mac or LAMP for Linux) that is basically a web server in a .exe. It's a lot of hassle but it'll work.
Tried googling for a readily available script, but to no avail. I'm trying to find a script that does the below. Im not sure of there is a name for it.
Thank you in advance!
Function: Banner rotator with a single URL (PHP based)
Example:
User uploads 5 images (468x60px)
The system generates a a single image URL (e.g. http://demo.com/image.gif)
When user goes to the generated URL, it randomly shows 1 of his 5 images
Every time he refreshes the URL, it randomly shows him another one of his images
You can have the server-side code that processes the given URL return a random image each time. If you specify the server-side language (PHP, ASP.Net, JSP, ...) that you are using, I can give an example.
The URL can be something like
http://demo.com/image/
It does not need to have a specific image name in it.
The key is to ensure that the browser does not try and cache that URL. Set appropriate cache headers when returning the image. Again, the mechanics of doing that are specific to your language.
PHP Example
This short tutorial shows you now to select a random image from a folder of images
http://www.heckdesigns.com/tutorials/tutorial-pull-in-a-random-image-from-a-folder-with-php/
URL
You really should not have to require your URL to end in .png or whatever. If you set the Content-Type appropriately (as the tutorial above does), any web browser should display it properly. If that is in fact a requirement, you can use Apache rewrite rules to do that.
See
mod_rewrite and image redirecting