Odoo 12 : How to render pdf throught web? - odoo-12

I'm trying to get pdf from web but when I click the button to render the pdf, I get the error : the file is in text/plain. Here is the code:
#http.route('/comande/suivi/<int:orderid>', type='http', auth='user', website=True)
def print_suivi(self, orderid, **kw):
pdf = request.env.ref('modul_name.report_model_name').report_action(orderid, data={'order': orderid})
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf)),
('Content-Disposition', 'attachment; filename="report.pdf"')]
return request.make_response(pdf, headers=pdfhttpheaders)`
Can you help me? Thank you

After adding render_qweb_pdf() you don't need to use report_action() method. Try to do something like this :
pdf_report = request.env['report.module_name.report_template_name']
pdf, _ = request.env.ref('module_name.report_name').sudo().with_context().render_qweb_pdf(pdf_report)
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
return request.make_response(pdf, headers=pdfhttpheaders)

Related

Excel file send through Send grid attachment C# is corrupted

I'm using sendgrid to send mails with attachments. But seems like excel file is corrupted in the mail. This is the code I'm using
byte[] byteData = System.Text.Encoding.ASCII.GetBytes(File.ReadAllText(#"fullpath\test.xlsx"));
msg.Attachments = new List<SendGrid.Helpers.Mail.Attachment>
{
new SendGrid.Helpers.Mail.Attachment
{
Content = Convert.ToBase64String(byteData),
Filename = "test.xlsx",
Type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
Disposition = "attachment"
}
};
On opening of excel file, I'm getting a popup "We found a problem with content...If you trust click "Yes". On Yes, Excel cannot open this file. Can anyone please help me on this
#Sendgrid
Twilio SendGrid developer evangelist here.
I think the issue may be that you are getting the byte data by reading the file as text and then converting that text to bytes through the lens of ASCII encoding. It may work better to just read the file as bytes initially.
Try:
byte[] byteData = File.ReadAllBytes(#"fullpath\test.xlsx");
msg.Attachments = new List<SendGrid.Helpers.Mail.Attachment>
{
new SendGrid.Helpers.Mail.Attachment
{
Content = Convert.ToBase64String(byteData),
Filename = "test.xlsx",
Type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
Disposition = "attachment"
}
};
Try below
msg.AddAttachment("test.xlsx"); // Physical file path
Make assure file path is relevant
or You try with Bytes as well,
var bytes = File.ReadAllBytes(filePath);
var file = Convert.ToBase64String(bytes);
msg.AddAttachment("Name.xls", file);

Downloading csv file using Play Framework?

I want to add to my app a simple button that on click will call an Action that will create a csv file from two lists I have and download it to the user computer.
This is my Action:
def createAndDownloadFile = Action {
val file = new File("newFile.csv")
val writer = CSVWriter.open(file)
writer.writeAll(List(listOfHeaders, listOfValues))
writer.close()
Ok.sendFile(file, inline = false, _ => file.getName)
}
but this is now working for me, the file is not getting downloaded from the browser...
im expecting to see the file get downloaded by the browser, i thought Ok.sendFile should do the trick..
thanks!
You can use Enumerators and streams for that. It should work like this:
val enum = Enumerator.fromFile(...)
val source = akka.stream.scaladsl.Source.fromPublisher(play.api.libs.streams.Streams.enumeratorToPublisher(enum))
Result(
header = ResponseHeader(OK, Map(CONTENT_DISPOSITION → "attachment; filename=whatever.csv.gz")),
body = HttpEntity.Streamed(source.via(Compression.gzip), None, None)
)
This will actually pipe the download through gzip. Just remove the .via(Compression.gzip) part if that is not needed.

Scrape different pages using Scrapy

I've been trying to scrape different pages. First, I scrape a URL from the first page using the xpath(#href) at the parse function. And then I try to scrape the article at that URL, from the parse function request callback. But it doesn't work.
How can I solve this issue? Here is my code:
import scrapy
from string import join
from article.items import ArticleItem
class ArticleSpider(scrapy.Spider):
name = "article"
allowed_domains = ["http://joongang.joins.com"]
j_classifications = ['politics','money','society','culture']
start_urls = ["http://news.joins.com/politics",
"http://news.joins.com/society",
"http://news.joins.com/money",]
def parse(self, response):
sel = scrapy.Selector(response)
urls = sel.xpath('//div[#class="bd"]/ul/li/strong[#class="headline mg"]')
items = []
for url in urls:
item = ArticleItem()
item['url'] = url.xpath('a/#href').extract()
item['url'] = "http://news.joins.com"+join(item['url'])
items.append(item['url'])
for itm in items:
yield scrapy.Request(itm,callback=self.parse2,meta={'item':item})
def parse2(self, response):
item = response.meta['item']
sel = scrapy.Selector(response)
articles = sel.xpath('//div[#id="article_body"]')
for article in articles:
item['article'] = article.xpath('text()').extract()
items.append(item['article'])
return items
The problem here is that you restrict the domains: allowed_domains = ["http://joongang.joins.com"]
If I change this to allowed_domains = ["joins.com"] I get results in parse2 and article text is extracted -- as unicode but this is OK since the site is not written in latin characters.
And by the way: you can use response.xpath() instead of creating a selector over the response object. This requires some less code and makes it easier to code.

Docx to Google Doc using Google Script

I have a lot of docx files ( ~ 72 ) , their MIMETYPE is :
application/vnd.openxmlformats-officedocument.wordprocessingml.document
and I want to convert all of them to GoogleDocument so I can edit them online to do so I need them to be
application/vnd.google-apps.document
Is this possible ? I've tried with blob but nothing works , there is a way to create a new google doc with the same format ?
Got it .
var docx = DriveApp.getFileById("###");
var newDoc = Drive.newFile();
var blob =docx.getBlob();
var file=Drive.Files.insert(newDoc,blob,{convert:true});
The {convert:true} convert it .
Ps : you need to set document name since it's not included in teh blob
DocumentApp.openById(file.id).setName(docx.getName());

jasper reports with HTML Format

Am using jasper reports library with GWT application.
The reports is generated well with CSV format but with HTML format it generate the HTML page with icons of missing picture.
I know that jasper using transparent image called "PX", this image not found.
How can i solve this problem?
Thanks in Advance
If you don't have images to show then you can do this:
JasperPrint jasperPrint = JasperFillManager.fillReport(path, parameters, con);
JRHtmlExporter htmlExporter = new JRHtmlExporter();
response.setContentType("text/html");
request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);
htmlExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
htmlExporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);
htmlExporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, false);
htmlExporter.exportReport();
The important line is this one:
htmlExporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, false);
That will make all the "px" images disappear.
Try passing in your image as a parameter to the report so you won't have to worry about image paths.
You can set the type of the parameter as a BufferedImage or whatever image class suits.
My solution was to use data URIs. This isn't very elegant since it bloats the size of the HTML and doesn't work in IE prior to IE8, but it does allow you to not bother worrying about creating files out of the image attachments Jasper sends you either.
If you're going to implement this, you want to add this argument to your request:
<argument name="IMAGES_URI"><![CDATA[data:]]></argument>
Then you need to parse the report HTML that JasperServer sends back:
foreach ($attachments as $name => $attachment) {
// Cut off the cid: portion of the name.
$name = substr($name, 4);
// Replace any image URIs with a data: uri.
if (strtolower(substr($name, 0, 4)) !== 'uuid' && strtolower($name) !== 'report') {
if (strtoupper(substr($attachment, 0, 3)) === 'GIF') {
// It's a GIF.
$report = str_replace("data:$name", 'data:image/gif;base64,' . base64_encode($attachment), $report);
} elseif (/* more file type tests */) {
// and so on...
}
}
}
For large images, it's best to do as Gordon suggested and pass in a parameter specifying the URL of a file that is permanently stored on the server. This method is more of a failsafe for gracefully handling any unexpected images JasperServer tries throwing at you.
I'm a bit late to this discussion but this is what I've been using. The key is to pass the imagesMap to both the session attribute and exporter parameter, and to set the IMAGES_URI exporter parameter.
private void exportReportAsHtml(HttpServletRequest request, HttpServletResponse response, JasperPrint jasperPrint) throws IOException, JRException {
response.setContentType("text/html");
request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);
Map imagesMap = new HashMap();
request.getSession().setAttribute("IMAGES_MAP", imagesMap);
JRHtmlExporter exporter = new JRHtmlExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, response.getWriter());
exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, imagesMap);
exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "image?image=");
exporter.exportReport();
}