I installed dompdf using composer
composer require dompdf/dompdf
in my controller i have this
use Dompdf\Dompdf;
....
function actionPdf() {
$dompdf = new DOMPDF();
$dompdf->loadHtml('<h1>hello world</h1>');
$dompdf->setPaper('A4', 'landscape');
$dompdf->render();
}
but all i get is a blank PDF. When i check app.log i see this
2021-09-02 20:20:41 [127.0.0.1][262][-][error][yii\web\HeadersAlreadySentException] yii\web\HeadersAlreadySentException: Headers already sent in on line 0. in C:\xampp\htdocs\yii2\vendor\yiisoft\yii2\web\Response.php:373
Stack trace:
#0 C:\xampp\htdocs\yii2\vendor\yiisoft\yii2\web\Response.php(346): yii\web\Response->sendHeaders()
#1 C:\xampp\htdocs\yii2\vendor\yiisoft\yii2\base\Application.php(398): yii\web\Response->send()
#2 C:\xampp\htdocs\yii2\frontend\web\index.php(64): yii\base\Application->run()
#3 {main}
Any Idea how to fix this? Thanks
Not sure the exact proper Yii way, but in my case this works:
Note the exit(); at the end.
// instantiate and use the dompdf class
$dompdf_options = new \Dompdf\Options();
$dompdf_options->setDpi(150);
$dompdf = new Dompdf($dompdf_options);
$dompdf->loadHtml($html);
// (Optional) Setup the paper size and orientation
$dompdf->setPaper('A4');
// Render the HTML as PDF
$dompdf->render();
$attachment=false;
$options=[
"Attachment" => $attachment
];
// Output the generated PDF to Browser
$dompdf->stream('Informe de vehĂculo', $options);
exit();
I guess the problem is caused by how Yii renders the data. But by calling exit() you prevent any of that to happen.
Related
I am trying to implement GWT image upload functionality. I have made the required code change but for some reason upload is not happening. At the server side the image is not being received. So I checked at the client side (browser) the request header and content and then I found that Content-Length: 44 (just 44). Then I realized that the image is not being sent to server on from submission. Please check the below GWT code.
VerticalPanel vp = new VerticalPanel();
vp.add(CommonFormLayoutUtil.createLabel("Upload"));
final FormPanel form = new FormPanel();
form.setAction("CGIImageUpload");
// set form to use the POST method, and multipart MIME encoding.
form.setEncoding(FormPanel.ENCODING_MULTIPART);
form.setMethod(FormPanel.METHOD_POST);
final FileUpload fileUpload = new FileUpload();
Button uploadButton = new Button("Upload");
uploadButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
//get the filename to be uploaded
String filename = fileUpload.getFilename();
if (filename.length() == 0) {
showError("No File Specified!", null);
} else {
//submit the form
form.submit();
}
}
});
vp.add(fileUpload);
vp.add(uploadButton);
form.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
#Override
public void onSubmitComplete(SubmitCompleteEvent event) {
// When the form submission is successfully completed, this
//event is fired. Assuming the service returned a response
//of type text/html, we can get the result text here
showError(event.getResults(), null);
}
});
form.add(vp);
Am i missing anything here? Please suggest.
Thanks.
FormPanel states the following:
"This panel can be used to achieve interoperability with servers that accept traditional HTML form encoding. The following widgets (those that implement com.google.gwt.user.client.ui.HasName) will be submitted to the server if they are contained within this panel" (emphasis mine)
You need to set the name of the FileUpload widget otherwise it will not be submitted by the FormPanel.
fileUpload.setName("someName");
Try setting this and it should work
On a cs-cart project, I am looking for a clean way to automate the migration of the current theme in a fully automatic manner.
Migrating the theme files is easy since each theme is located in a dedicated directory.
Nevertheless, some pages are created using the layouts WYSIWIG editor from the backend. This editor as a nice feature that allows to generate an XML file that describes all the layouts and can be imported back into another environment. This requires manual operation (logging into the backend, clicking the button...) and I would like to fully automate this.
So far, the only solution I was able to find is to migrate the data directly from the database, by generating a dump of the layout related-tables and importing it into the target environment. This solution seems to work but is a bit risky in my opinion.
Does cs-cart provide a command-line interface to export and import the current layouts?
I wrote a small script for this task:
<?php
use Tygh\BlockManager\Layout;
use Tygh\BlockManager\Exim;
if ($mode == "do") {
$location_ids = array();
$default_layout_data = Layout::instance()->getDefault();
$layout_id = $default_layout_data['layout_id'];
$content = Exim::instance()->export($layout_id, $location_ids);
header("Content-Type: text/xml");
header("Content-Length: " . strlen($content));
header('Content-Disposition: attachment; filename=layouts.xml');
header('Expires: 0');
print $content;
exit();
}
if you put this code to a controller file (for example into your /app/addons/my_changes/controllers/backend/layout_export.php) and call this via url (in my case: /youradmin.php?dispatch=layout_export.do), it will download the default theme's main layout structure.
Please note, that I'm working with version 4.3.3. However I think this code will work any type of CS-Cart from version 4.x
Full solution (with my_changes add-on)
/app/addons/my_changes/schemas/permissions/trusted_controllers.post.php
<?php
$schema['layout_exim']['allow']['export'] = true;
$schema['layout_exim']['allow']['import'] = true;
return $schema;
/app/addons/my_changes/controllers/backend/layout_exim.php
<?php
use Tygh\BlockManager\Layout;
use Tygh\BlockManager\Exim;
if ($mode == "export") {
$location_ids = array();
$default_layout_data = Layout::instance()->getDefault();
$layout_id = $default_layout_data['layout_id'];
$content = Exim::instance()->export($layout_id, $location_ids);
header("Content-Type: text/xml");
header("Content-Length: " . strlen($content));
header('Content-Disposition: attachment; filename=layouts.xml');
header('Expires: 0');
print $content;
exit();
} elseif ($mode == "import") {
$result = Exim::instance()->importFromFile($_REQUEST['filepath']);
if ($result) {
print "true";
} else {
print "false";
}
exit();
}
After it, please clear your cache. If you do everything right, you will be able to call these 2 controllers without authentication (however I suggest you to set passwords in the get parameters, because right now, this is very unsafe!)
To call the controllers via URL:
http://path-to-your-admin.com/admin.php?dispatch=layout_exim.import&filepath=path/to/file
http://path-to-your-admin.com/admin.php?dispatch=layout_exim.export
I have a requirement in which I have to generate a pdf and then on click of button "SHOW PDF", I have to display on another window.
I have been able to generate a pdf using IText and stored in my machine. I get a java.io.File object as my return value from my backend library which needs to be displayed on the screen. Can someone please guide me how to do this?
My xhtml file has the following code snippet:
<h:commandLink action="PdfDisplayRedirect.xhtml" target="_blank">show PDF</h:commandLink>
my PdfDisplayRedirect.xhtml has the following code:
<p:media value="#{pdfGenerationAction.fileName}" width="100%" height="300px">
Your browser can't display pdf, <h:outputLink value="InitialExamination33.pdf">click</h:outputLink> to download pdf instead.
My backing bean has the following code:
private File initialExaminationFile;
private generateFile(){
this.initialExaminationFile = backendService.generateFile();
}
On clicking, I get a new window opened but the pdf file is not displayed.. Instead my screen from where I had invoked the command gets displayed there.
Any help would be really appreciated.
Thanks
Thanks for the response and no response.
I have found a solution myself which I would like to post so that those looking for a solution can use it.
My xhtml file included a commandlink
<p:commandLink actionListener="#{pdfGenerationAction.generatePDF(initialExaminationEMRAction.patientID)}" oncomplete="window.open('PdfDisplayRedirect.xhtml')">broadcast Msg</p:commandLink>
My pdfGenerationAction bean file had the following lines of code:
FileInputStream fis = new FileInputStream(this.initialExaminationFile);
//System.out.println(file.exists() + "!!");
//InputStream in = resource.openStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum); //no doubt here is 0
//Writes len bytes from the specified byte array starting at offset off to this byte array output stream.
System.out.println("read " + readNum + " bytes,");
}
this.reportBytes = buf;
}
I converted my file into bytearraystream and made it available in my session. Then I followed the suggestion given by BalusC at Unable to show PDF in p:media generated from streamed content in Primefaces
I've trying to get properly work kcaptcha class from kcaptcha.ru in my own component. 'Cause class not build for Joomla natively I break my brain on the wall.
And at the beginning...
I've a url to image generated by this class like: http://.../index.php&task=captcha&format=raw
In main controller I've put method
function captcha() {
include(JPATH_COMPONENT.DS.'libraries'.DS.'captcha'.DS.'kcaptcha'.DS.'kcaptcha.php');
$session = &JSession::getInstance('default', array());
$captcha = new KCAPTCHA();
if ($session) {
$session->set('captcha_keystring', $captcha->getKeyString());
}
}
And I've see in browser
When I request an image from the class all working good but in my component I cannot set session variables.
Any ideas how to fix this problem?
And problem solved successfully.
For &format=raw in controller Joomla set default mime-type to text/html.
For healing this issue developer must reset mime/type via setting
$document = &JFactory::getDocument();
$document->setMimeEncoding('image/png');
mime/encoding off course depends on you needs.
Can anyone help me in displaying PDF document in JSF page in iframe only?
Thanks in advance,
Suresh
Just use <iframe> the usual way:
<iframe src="/path/to/file.pdf"></iframe>
If your problem is rather that the PDF is not located in the WebContent, but rather located somewhere else in disk file system or even in a database, then you basically need a Servlet which gets an InputStream of it and writes it to the OutputStream of the response:
response.reset();
response.setContentType("application/pdf");
response.setContentLength(file.length());
response.setHeader("Content-disposition", "inline; filename=\"" + file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
close(output);
close(input);
}
This way you can just point to this servlet instead :) E.g.:
<iframe src="/path/to/servlet/file.pdf"></iframe>
You can find a complete example of a similar servlet in this article.
The <iframe> also works fine in JSF, assuming that you're using JSF 1.2 or newer. In JSF 1.1 or older you have to wrap plain vanilla HTML elements such as <iframe> inside a <f:verbatim> so that they will be taken into the JSF component tree, otherwise they will be dislocated in the output:
<f:verbatim><iframe src="/path/to/servlet/file.pdf"></iframe></f:verbatim>
I recommend you to have a look at http://www.jpedal.org/. You can convert each of the pdf pages to images and deliver them separately to the browser.
This approach is more secure for your application, since the pdf is never send to the client.