Hiroki MIZUNO avatar Hiroki MIZUNO committed 263291d

add excel shape drawer

Comments (0)

Files changed (1)

blockdiagcontrib_excelshape/excelshape.py

-# -*- coding: utf-8 -*- 
-#  Copyright 2012 MIZUNO Hiroki
+# -*- coding: utf-8 -*- #  Copyright 2012 MIZUNO Hiroki
 # 
 #  Licensed under the Apache License, Version 2.0 (the "License");
 #  you may not use this file except in compliance with the License.
 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
-try:
-    from PIL import Image
-    from PIL import ImageDraw
-    from PIL import ImageFont
-    from PIL import ImageFilter
-except ImportError:
-    import Image
-    import ImageDraw
-    import ImageFont
-    import ImageFilter
+import re
+import base64
+import win32com.client
+import os
+import os.path
+from blockdiag.utils import XY
+from blockdiag.imagedraw import base
 
+class ExcelShapeImageDraw(base.ImageDraw):
+    MSO_SHAPE_RECTANGE = 1
+    MSO_SHAPE_OVAL     = 9
+    MSO_SHAPE_ARC      = 25
+    XL_CENTER = -4108
+
+    def __init__(self, filename, **kwargs):
+        self.excel         = win32com.client.Dispatch("Excel.Application") 
+        self.excel.Visible = True
+        self.DisplayAlerts = False 
+        self.book = self.excel.Workbooks.Add()
+
+    def set_canvas_size(self, size):
+        pass
+
+    def path(self, pd, **kwargs):
+        pass
+
+    def rgb(self, rgb):
+        if rgb == "white":
+            return 0xFFFFFF
+        else:
+            r,g,b = rgb
+            return (r << 16) + (g << 8) + b
+
+    def width(self, box):
+        return box[2] - box[0]
+
+    def height(self, box):
+        return box[3] - box[1]
+
+    def set_style(self, shape, kwargs):
+        fill    = kwargs.get('fill')
+        outline = kwargs.get('outline')
+        tick    = kwargs.get('tick')
+
+        if tick != None:
+            shape.Line.Weight = 1
+
+        if outline != None:
+            shape.Line.ForeColor.RGB = self.rgb(outline)
+        if fill != None:
+            shape.Fill.ForeColor.RGB = self.rgb(fill)
+
+    def rectangle(self, box, **kwargs):
+        left   = box[0]
+        top    = box[1]
+        width  = self.width(box)
+        height = self.height(box)
+
+        shape = self.book.ActiveSheet.Shapes.AddShape(self.MSO_SHAPE_RECTANGE, left, top, width, height);
+        self.set_style(shape, kwargs)
+
+    def text(self, xy, string, font, **kwargs):
+        pass
+
+    def textarea(self, box, string, font, **kwargs):
+        left   = box[0]
+        top    = box[1]
+        width  = self.width(box)
+        height = self.height(box)
+
+        fill = kwargs.get('fill', 'none')
+        shape = self.book.ActiveSheet.Shapes.AddShape(self.MSO_SHAPE_RECTANGE, left, top, width, height)
+        shape.Line.Visible = 0
+
+        shape.Fill.ForeColor.RGB = 0xFFFFFF
+        shape.Fill.Visible = False
+        chars = shape.TextFrame.Characters()
+        chars.Text = string
+        chars.Font.Color = self.rgb(fill)
+        chars.Font.Size = font.size
+
+        if kwargs['halign'] == 'center':
+            shape.TextFrame.HorizontalAlignment = self.XL_CENTER
+        shape.TextFrame.VerticalAlignment = self.XL_CENTER
+
+    def line(self, xy, **kwargs):
+        x1,y1 = xy[0]
+        x2,y2 = xy[1]
+        self.book.ActiveSheet.Shapes.AddLine(x1, y1, x2, y2)
+
+    def arc(self, xy, start, end, **kwargs):
+        w = self.width(xy)
+        h = self.height(xy)
+        pt = XY(xy[0], xy[1])
+        shape = self.book.ActiveSheet.Shapes.AddShape(self.MSO_SHAPE_ARC, pt.x, pt.y, w, h)
+        shape.Adjustments.SetItem(1, start - end)
+        shape.Rotation = start + 90
+        shape.Left     = xy[0]
+        shape.Top      = xy[1]
+
+    def ellipse(self, xy, **kwargs):
+        w = self.width(xy)
+        h = self.height(xy)
+        pt = XY(xy[0], xy[1])
+
+        shape = self.book.ActiveSheet.Shapes.AddShape(MSO_SHAPE_OVAL, pt.x, pt.y, w, h)
+        self.set_style(shape, kwargs)
+
+    def polygon(self, xy, **kwargs):
+        form = self.book.ActiveSheet.Shapes.BuildFreeform(0, xy[0][0], xy[0][1])
+
+        for (x,y) in xy[1:]:
+            form.AddNodes(0, 0, x, y) 
+        shape = form.ConvertToShape()
+        self.set_style(shape, kwargs)
+
+    def loadImage(self, filename, box):
+        pass
+
+    def save(self, filename, size, format):
+        path = os.path.abspath(filename)
+        if os.path.exists(path):
+            os.remove(path)
+        self.book.SaveAs(path, 56)
+        self.excel.Quit()
 
 def setup(self):
-    pass
+    from blockdiag.imagedraw import install_imagedrawer
+    install_imagedrawer('shape.xls', ExcelShapeImageDraw)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.