scalaはHighChartsが生成したSVG画像のダウンロードを実現

7196 ワード

 1 @WebServlet(name = "Highcharts-Chart-Export", urlPatterns = Array[String]("/svg"))
 2 @MultipartConfig
 3 @Singleton
 4 class ExportSVGServlet extends HttpServlet with Disposable {
 5   val REQUEST_METHOD_POST = "POST"
 6   val CONTENT_TYPE_MULTIPART = "multipart/"
 7   val ORBIDDEN_WORD = "<!ENTITY"
 8 
 9   override def service(req: HttpServletRequest, res: HttpServletResponse) = {
10     req.setCharacterEncoding("utf-8")
11     res.setCharacterEncoding("utf-8")
12 
13     val multi = isMultipartRequest(req)
14     val svg = getParameter(req, "svg", multi)
15     val width = getParameter(req, "width", multi)
16     val mime = getParameter(req, "type", multi)
17 
18     writeFileContentToHttpResponse(svg, "patent-analysis-imageexport-" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()), if (width != null) width.toFloat else 0f, mime, res);
19   }
20 
21   def writeFileContentToHttpResponse(svg: String,
22     filename: String, width: Float, mime: String,
23     response: HttpServletResponse) = {
24 
25     var stream = new ByteArrayOutputStream()
26 
27     stream = SVGRasterizer.transcode(stream, svg, mime, width)
28 
29     response.reset()
30     response.setContentLength(stream.size())
31     response.setCharacterEncoding("utf-8")
32     response.setHeader("Content-disposition", "attachment; filename=" + filename + {
33       mime.toLowerCase() match {
34         case "image/png" => ".png"
35         case "image/jpeg" => ".jpg"
36         case "application/pdf" => ".pdf"
37         case _ => mime.toLowerCase()
38       }
39     })
40     response.setHeader("Content-type", mime)
41     using(response.getOutputStream()) { out => out.write(stream.toByteArray()) }
42   }
43 
44   def isMultipartRequest(request: HttpServletRequest) = REQUEST_METHOD_POST.equalsIgnoreCase(request.getMethod()) && request.getContentType() != null && request.getContentType().toLowerCase().startsWith(CONTENT_TYPE_MULTIPART)
45 
46   private def getParameter(request: HttpServletRequest, name: String, multi: Boolean) = {
47     if (multi && request.getPart(name) != null) {
48       getValue(request.getPart(name));
49     } else {
50       request.getParameter(name);
51     }
52   }
53 
54   private def getValue(part: Part) =Source.fromInputStream(part.getInputStream(), "utf-8").mkString
55 
56   def getFilename(name: String) = if (name != None) name else "chart"
57 }