Reputation: 227
I'm trying to send a PDF file as an attachment in an email. I don't want to save pdf file on server or client machine. I've tried following. But it doesn't work. Please suggest correct way to do it.
ByteArrayOutputStream bytes = pdfRenderingService.render(template: "path to template", model: [account:account])
asynchronousMailService.sendMail {
multipart true
to emailID
subject emailSubject
html emailBodyContent
attachBytes "filename.pdf", "application/pdf", bytes
}
it doesn't work as it requires byte to send in attachment. And ByteArrayOutputStream
doesn't give output in bytes. Does anyone has solution for this ?
I tried bytes.toByteArray()
. But it gave following exception :
2014-11-03/22:25:35.994 [http-bio-8080-exec-9] ERROR errors.GrailsExceptionResolver - MissingMethodException occurred when processing request: [GET] /morningProc/approvalPdfFR
No signature of method: [B.call() is applicable for argument types: (java.lang.String, java.lang.String, [B) values: [Approval.pdf, application/pdf, [37, 80, ...]]
Possible solutions: wait(), any(), grep(), dump(), find(), collect(). Stacktrace follows:
groovy.lang.MissingMethodException: No signature of method: [B.call() is applicable for argument types: (java.lang.String, java.lang.String, [B) values: [Approval.pdf, application/pdf, [37, 80, ...]]
Possible solutions: wait(), any(), grep(), dump(), find(), collect()
at com.crm.MultilingualEmailService$_$tt__sendEmailFormateWithAttachment_closure14$$EOuZNrCU.doCall(MultilingualEmailService.groovy:79)
at grails.plugin.mail.MailService.sendMail(MailService.groovy:39)
at MailGrailsPlugin$_configureSendMail_closure7.doCall(MailGrailsPlugin.groovy:180)
at com.crm.MultilingualEmailService$$EOuZNrCS.$tt__sendEmailFormateWithAttachment(MultilingualEmailService.groovy:74)
at com.crm.MorningProcController$$EOuZVK1N.approvalPdfFR(MorningProcController.groovy:882)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:200)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Even I tried using Wkhtmltopdf plugin. but it gave error. I tried following code:
byte[] pdfData = wkhtmltoxService.makePdf(
view: "/morningProc/approvalPdfFR",
model: [account:accountInst],
header: "",
footer: "",
marginLeft: 20,
marginTop: 35,
marginBottom: 20,
marginRight: 20,
headerSpacing: 10
)
But unfortunately no luck. It throws exception :
Cannot find wkhtml executable at [:] trying to make it available with the makeBinaryAvailableClosure
2014-11-04/00:50:35.985 [http-bio-8080-exec-2] ERROR errors.GrailsExceptionResolver - GroovyCastException occurred when processing request: [GET] /morningProc/approvalPdfFR
Cannot cast object 'groovy.util.ConfigObject@5ee8e41c' with class 'groovy.util.ConfigObject' to class 'groovy.lang.Closure' due to: groovy.lang.GroovyRuntimeException: failed to invoke constructor: public groovy.lang.Closure(java.lang.Object) with arguments: [[:]] reason: java.lang.InstantiationException. Stacktrace follows:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'groovy.util.ConfigObject@5ee8e41c' with class 'groovy.util.ConfigObject' to class 'groovy.lang.Closure' due to: groovy.lang.GroovyRuntimeException: failed to invoke constructor: public groovy.lang.Closure(java.lang.Object) with arguments: [[:]] reason: java.lang.InstantiationException
at org.wkhtmltox.WkhtmltoxService.makePdf(WkhtmltoxService.groovy:56)
at org.wkhtmltox.WkhtmltoxService.makePdf(WkhtmltoxService.groovy:35)
at com.crm.MorningProcController$$EOua5loZ.approvalPdfFR(MorningProcController.groovy:881)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:200)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Upvotes: 2
Views: 3547
Reputation: 559
You can achieve it via Grails Mail Plugin:
Note: Before using the below code snippet. You should have already configured the grails mail plugin in your Config.groovy file.
Use the following code snippet in you controller or service and then modify it as per your requirements:
def EmailSendingWithPDF {
sendMail {
multipart true // For attaching multiple files
from "[email protected]"
to "Sending_Email_address"
bcc "[email protected]"
subject "Your Subject Here"
html params.anyText
// An Example of automatic attachment with Image:
def logo_Example = Domain_Name.findById(id_number)
byte[] logoAttached = logo_Example?.myFile
inline 'logo', 'image/png', logoAttached
// An Example of automatic attachment with PDF:
def pdfFile
byte[] attachedPdf = pdfFile?.myFile
attach pdfFile.name, "application/pdf", attachedPdf
}
}
Upvotes: 0
Reputation: 227
Finally it worked for me. Following is the solution :
ByteArrayOutputStream bytes = pdfRenderingService.render(template: "path to template", model: [account:account])
asynchronousMailService.sendMail {
multipart true
to emailID
subject emailSubject
html emailBodyContent
attachBytes "filename.pdf", "application/pdf", bytes.toByteArray()
}
And also I did run clean up command. Also there is one tip, don't put the variable name of bytes as 'attachBytes'. Like : attachBytes "filename.pdf", "application/pdf", attachBytes.toByteArray()
It also caused me so much time to come to the solution.
Upvotes: 2