"""
 * @author Xiaobo Sun
 * created  on 23.06.2018
 * @copyright (C) 2018 Sogood International GmbH - all rights reserved
 * @licence
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
"""

import datetime
import json
import logging

from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle, Flowable
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch, cm
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.enums import TA_RIGHT, TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.pdfgen import canvas
from reportlab.lib.units import mm
from reportlab.graphics.barcode import createBarcodeDrawing
from . import stockup
import io
import textwrap

# Get an instance of a logger
logger = logging.getLogger('django')

pdfmetrics.registerFont(TTFont('DejaVuSans', 'fonts/DejaVuSans.ttf'))


class SampleFlowable(Flowable):
    """
    Sample Flowable Usage
    Usage : elements.append(SampleFlowable())
    """

    def __init__(self):
        Flowable.__init__(self)
        self.width = 50
        self.height = 50

    def draw(self) -> None:
        """
        Draw a line
        """
        self.canv.line(0, self.height, self.width, self.height)


class NumberedCanvas(canvas.Canvas):
    """
    Page Number - Canvas Sample
    """

    def __init__(self, *args, **kwargs):
        canvas.Canvas.__init__(self, *args, **kwargs)
        self._saved_page_states = []

    def showPage(self) -> None:
        """
        Show page
        """
        self._saved_page_states.append(dict(self.__dict__))
        self._startPage()

    def save(self) -> None:
        """
        Add page info to each page (page x of y)
        """
        # num_pages = len(self._saved_page_states)
        for state in self._saved_page_states:
            self.__dict__.update(state)
            # self.draw_page_number(num_pages)
            canvas.Canvas.showPage(self)
        canvas.Canvas.save(self)

    # def draw_page_number(self, page_count) -> None:
    #     """
    #     Draw page number
    #     :param page_count: page number
    #     """
    #     # Change the position of this to wherever you want the page number to be
    #     self.setFontSize(6)
    #     self.drawCentredString(100 * mm, 10 * mm,
    #                            "%d von %d" % (self._pageNumber, page_count))


class SogoodPrintable:
    """
    Main Class
    A4 is 210mm x 297mm, 8.27 x 11.69 inches. 1 inch is 72 points (not pixel)
    dimension 592 x 842 points
    """

    def __init__(self, buffer,
                 is_sogood,
                 platform_id,
                 order_date,
                 type,
                 tax,
                 customerCompany,
                 customerTitle,
                 customerSurname,
                 customerFirstname,
                 customerStreet,
                 customerPostcode,
                 customerCity,
                 customerCountry,
                 customerMail,
                 customerTelephone,
                 customerShippingCompany,
                 customerShippingSurname,
                 customerShippingFirstname,
                 customerShippingStreet,
                 customerShippingPostcode,
                 customerShippingCity,
                 customerShippingCountry,
                 customerShippingTelephone,
                 paymentMethod,
                 paymentDetails,
                 paidSum,
                 paidTax,
                 shippingMethod,
                 shippingDatails,
                 soldItems,
                 comment,
                 invoiceComment,
                 orderId,
                 billingNr,
                 userId,
                 userIdPlattform,
                 payment_date,
                 invoice_date,
                 shipping_date,
                 dealWith,
                 working_days,
                 elements):
        """
        :param buffer:
        :param is_sogood: False
        :param platform_id(new): 9876543210 : if afterbuy-id available, else goodone-order id
        :param order_date(new): "25.06.2018 09:30:00" - new
        :param type(new): 0 Angebot, 1 Auftragsbestätigung, 2 Lieferschein, 3 Rechnung
        :param tax(new): 19
        :param customerCompany: "Muster International GmbH"
        :param customerTitle(new): "Herr"
        :param customerSurname: "Müller"
        :param customerFirstname: "Thomas"
        :param customerStreet: "Hans-Kohl-Str. 27"
        :param customerPostcode: "64646"
        :param customerCity: "Heppenheim"
        :param customerCountry: "Deutschland"
        :param customerMail: "thomas.müller@muster.de"
        :param customerTelephone: "+49 151 00000000"
        :param customerShippingCompany: "Muster International GmbH"
        :param customerShippingSurname: "Müller"
        :param customerShippingFirstname: "Thomas"
        :param customerShippingStreet: "Hans-Kohl-Str. 27"
        :param customerShippingPostcode: "64646"
        :param customerShippingCity: "Heppenheim"
        :param customerShippingCountry: "Deutschland"
        :param paymentMethod: "Paypal"
        :param paymentDetails: "http://url_to_qrcode"
        :param paidSum: "289.00"
        :param paidTax(new): "50.00"
        :param shippingMethod: "DHL/DPD/EkremTranksport"
        :param shippingDatails: "28.06.2018"
        :param soldItems:
             {"items":
              [
                {
                  "ean": "4250755330211",
                  "quantity": "1",
                  "price": "310.99",
                  "comment": "ECHT GLAS DUSCHE DUSCHABTRENNUNG DUSCHKABINE AUS SICHERHEITSGLAS RAVENNA17-2",
                  "tax": "19",
                  "stammbezeichnung": "sbz1",
                  "packstueck": "1"
                 },
                {
                  "ean": "4250755304137",
                  "quantity": "3",
                  "price": "60.99",
                  "comment": "WC SITZ TOILETTENDECKEL KLODECKEL KLOBRILLE TOILETTENSITZ SOFTCLOSE WCD376",
                  "tax": "19",
                  "stammbezeichnung": "sbz1",
                  "packstueck": "1"
                },
                {
                  "ean": "4250755323091",
                  "quantity": "1",
                  "price": "260.99",
                  "comment": "140x200 cm Design Walk-In Duschabtrennung Bremen1 in grauem Glas mit 4-eckigem Stabilisator BRAM2 <br/>
                             Breite (cm): 140 cm <br/>
                             Stabilisator: 4 - eckig (BRAM2)",
                  "tax": "19",
                  "stammbezeichnung": "sbz1",
                  "packstueck": "1"
                },
                {
                  "ean": "4250755323091",
                  "quantity": "2",
                  "price": "520.99",
                  "comment": "LUXUS DUSCHE DUSCHWAND DUSCHABTRENNUNG AUS ECHTGLAS VARIABEL 80-120CM BREMEN 1s",
                  "tax": "19",
                  "stammbezeichnung": "sbz1",
                  "packstueck": "1"
                },
                {
                  "ean": "4251242935322",
                  "quantity": "1",
                  "price": "109.99",
                  "comment": "ABLAUFGARNITUR SIPHON DUSCHTASSE Ø90MM <br/> ABLAUFLOCH GERUCHVERSCHLUSS AL02",
                  "tax": "19",
                  "stammbezeichnung": "sbz1",
                  "packstueck": "1"
                },
                {
                  "ean": "4251242935322",
                  "quantity": "1",
                  "price": "29.95",
                  "comment": "Nano-M für Duschwand Wachbecken WC & <br/> Bildet SOGOOD",
                  "tax": "19",
                  "stammbezeichnung": "sbz1",
                  "packstueck": "1"
                },
                {
                  "ean": "4251242935322",
                  "quantity": "1",
                  "price": "29.95",
                  "comment": "Nano-M für Duschwand Wachbecken WC & <br/> Bildet SOGOOD",
                  "tax": "19",
                  "stammbezeichnung": "sbz1",
                  "packstueck": "1"
                 },
                {
                  "ean": "4251242935322",
                  "quantity": "1",
                  "price": "29.95",
                  "comment": "Nano-M für Duschwand Wachbecken WC & <br/> Bildet SOGOOD",
                  "tax": "19",
                  "stammbezeichnung": "sbz1",
                  "packstueck": "1"
                },
                {
                  "ean": "4250755323527",
                  "quantity": "1",
                  "price": "329.95",
                  "comment": "Bremen2ms 90x200 cm 10 mm (BR10703MS 90)",
                  "tax": "19",
                  "stammbezeichnung": "sbz1",
                  "packstueck": "1"
                },
                {
                  "ean": "4250755323091",
                  "quantity": "1",
                  "price": "260.99",
                  "comment": "140x200 cm Design Walk-In Duschabtrennung Bremen1 in grauem Glas mit 4-eckigem Stabilisator BRAM2 <br/>
                            Breite (cm): 140 cm <br/>
                            Stabilisator: 4 - eckig (BRAM2)",
                  "tax": "19",
                  "stammbezeichnung": "sbz1",
                  "packstueck": "1"
                },
                {
                  "ean": "",
                  "quantity": "1",
                  "price": "-260.99",
                  "comment": "4% Rabatt auf Ihre Bestellung",
                  "tax": "19",
                  "stammbezeichnung": "sbz1",
                  "packstueck": "1"
                },
                {
                  "ean": "",
                  "quantity": "1",
                  "price": "-300.99",
                  "comment": "5% Rabatt auf Ihre Bestellung",
                  "tax": "19",
                  "stammbezeichnung": "sbz1",
                  "packstueck": "1"
                }
              ]
            }
        :param comment: "testing memo..."
        :param invoiceComment: "testing memo..."
        :param orderId: "1197839669"
        :param billingNr: "206437"
        :param userId: "1129167235"
        :param userIdPlattform: "Amazon-t4zhnxnjgrj83v3@marketplace.amazon.fr"
        :param payment_date: "25.06.2018 09:30:00"
        :param invoice_date: "25.06.2018 09:30:00"
        :param shipping_date: "25.06.2018 09:30:00"
        :param deal_with: ""
        :param working_days: 3
        """
        self._buffer = buffer
        self._type = type
        self._is_sogood = is_sogood
        self._is_otto = (userIdPlattform == "96994_sogood-de-otto")
        self._platform_id = platform_id
        self._order_date = order_date
        self._tax = tax
        self._customer_company = customerCompany
        self._customer_title = customerTitle
        self._customer_surname = customerSurname
        self._customer_firstname = customerFirstname
        self._customer_street = customerStreet
        self._customer_postcode = customerPostcode
        self._customer_city = customerCity
        self._customer_country = customerCountry
        self._customer_mail = customerMail
        self._customer_Telephone = customerTelephone
        self._customer_shipping_company = customerShippingCompany
        self._customer_shipping_surname = customerShippingSurname
        self._customer_shipping_firstname = customerShippingFirstname
        self._customer_shipping_street = customerShippingStreet
        self._customer_shipping_postcode = customerShippingPostcode
        self._customer_shipping_city = customerShippingCity
        self._customer_shipping_country = customerShippingCountry
        self._customer_shipping_telephone = customerShippingTelephone
        self._payment_method = paymentMethod
        self._payment_details = paymentDetails
        self._payment_sum = paidSum
        self._payment_tax = paidTax
        self._shipping_method = shippingMethod
        self._shiping_details = shippingDatails
        self._sold_items = soldItems
        self._comment = comment
        self._invoice_comment = invoiceComment
        self._orderId = orderId
        self._billingNr = billingNr
        self._userId = userId
        self._userIdPlattform = userIdPlattform
        self._payment_date = payment_date
        self._invoice_date = invoice_date
        self._shipping_date = shipping_date
        self._deal_with = dealWith
        self._working_days = working_days
        self._elements = elements

    def header(self, c, doc, is_first_page) -> None:
        """
        Header on each page
        :param c: Canvas
        :param doc: SimpleDocTemplate
        """

        logger.info("deliverynote.py header() " + self._customer_country + " xiaobo")

        styles = getSampleStyleSheet()
        styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
        styles.add(ParagraphStyle(name='Right', alignment=TA_RIGHT))

        logo = "images/doporro.png"
        if self._is_otto == True:
            logo = "images/otto.jpg"
        elif self._is_sogood == 'True':
            logo = "images/logo.png"
        else:
            logo = "images/maimai.png"
        im = Image(logo, 2.4 * inch, 0.8 * inch)
        w, h = im.wrap(doc.width, doc.bottomMargin)
        im.drawOn(c, doc.width / 2 + doc.leftMargin - w / 2, doc.height + doc.bottomMargin)

        if is_first_page:
            customer_addr = """<font size="10">
                  %s %s %s <br/>
                  %s <br/>
                  %s <br/>
                  <b>%s, %s</b> <br/>
                  <b>%s</b> <br/>
                  RTel: %s <br/>
                  LTel: %s <br/>
                  </font>
                  """ % ("" if self._customer_title is None else self._customer_title,
                         self._customer_firstname if self._customer_shipping_firstname is None else self._customer_shipping_firstname,
                         self._customer_surname if self._customer_shipping_surname is None else self._customer_shipping_surname,
                         self._customer_company if self._customer_shipping_company is None else self._customer_shipping_company,
                         self._customer_street if self._customer_shipping_street is None else self._customer_shipping_street,
                         self._customer_postcode if self._customer_shipping_postcode is None else self._customer_shipping_postcode,
                         self._customer_city if self._customer_shipping_city is None else self._customer_shipping_city,
                         self._customer_country if self._customer_shipping_country is None else self._customer_shipping_country,
                         "" if self._customer_Telephone is None else self._customer_Telephone,
                         "" if self._customer_shipping_telephone is None else self._customer_shipping_telephone
                         )
            customer_addr_p = Paragraph(customer_addr, styles["Normal"])
            vendor_maimai24_addr = """<font size="10">
                          Mai & Mai GmbH <br/>
                          Gutenbergring 1 <br/>
                          63110 Rodgau Deutschland <br/>
                          Telefon: +49 6106 6670592 <br/>
                          www.maimai24.de <br/>
                          %s
                          </font>
                          """ % (datetime.datetime.now().strftime('%d.%m.%Y %H:%M:%S'))
            vendor_sogood_addr = """<font size="10">
                          Sogood International GmbH <br/>
                          Gutenbergring 1 <br/>
                          63110 Rodgau Deutschland <br/>
                          Telefon: +49 6106 6667585 <br/>
                          www.sogood.de <br/>
                          %s
                          </font>
                          """ % (datetime.datetime.now().strftime('%d.%m.%Y %H:%M:%S'))
            # vendor_addr_p = None
            if self._is_sogood == 'True':
                vendor_addr_p = Paragraph(vendor_sogood_addr, styles["Right"])
            else:
                vendor_addr_p = Paragraph(vendor_maimai24_addr, styles["Right"])
            data = [[customer_addr_p, vendor_addr_p]]
            table = Table(data, colWidths=4 * inch)

            style = TableStyle([
                ('FONT', (0, 0), (-1, -1), 'Helvetica'),
                ('LEFTPADDING', (0, 0), (-1, -1), 60),  # not clean solution, but works somehow
                ('RIGHTPADDING', (0, 0), (-1, -1), 60),  # not clean solution, but works somehow
            ])

            table.setStyle(style)
            w1, h1 = table.wrap(doc.width, doc.bottomMargin)
            table.drawOn(c, doc.width / 2 + doc.leftMargin - w1 / 2, doc.height + doc.bottomMargin - h)

    def footer(self, c, doc) -> None:
        """
        Footer on each page
                Runs demo demonstrating usage of Spreadsheet Tables.
        :param c: Canvas
        :param doc: SimpleDocTemplate
        """

        if self._is_sogood == 'True':
            data = [
                ["Sogood International GmbH", "Telefon: +49 6106 6667585", "Amtsgericht Offenbach", "Bankverbindung:",
                 "BIC: DRESDEFFXXX"],
                ["Gutenbergring 1", "E-Mail: info@sogood.de", "HRB 42229", "Commerzbank", "IBAN:"],
                ["63110 Rodgau", "", "Geschäftsführerin: Shaoyang Huang".encode('utf-8'), "BLZ: 50080000",
                 "DE33500800000635289300"],
                ["Deutschland", "", "", "Konto: 0635289300", "USt-IdNr:DE DE814341426"],
            ]
        else:
            data = [
                ["Mai & Mai GmbH", "Telefon: +49 6106 6670592", "Amtsgericht Offenbach", "Bankverbindung:",
                 "BIC: COBADEFF004"],
                ["Gutenbergring 1", "EMail:info@maimai24.de", "HRB 44229", "Commerzbank", "IBAN:"],
                ["63110 Rodgau", "", "Geschäftsführerin: Wei Tao".encode('utf-8'), "BLZ: 50040000",
                 "DE7250 0400000413058900"],
                ["Deutschland", "", "", "Konto: 4130589 00", "UStIdNr: DE 265808049"],
            ]

        style = TableStyle([
            ('FONT', (0, 0), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 6),
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ])

        # Configure style and word wrap
        # s = getSampleStyleSheet()
        # s = s["BodyText"]
        # s.wordWrap = 'CJK'
        # data2 = [[Paragraph(cell, s) for cell in row] for row in data]
        # t = Table(data2)
        table = Table(data, colWidths=[3.3 * cm], rowHeights=0.3 * cm)
        table.setStyle(style)

        w, h = table.wrap(doc.width, doc.bottomMargin)
        table.drawOn(c, doc.leftMargin, h)

    def header_footer_first_page(self, c, doc) -> None:
        """
        First Page
        :param c: Canvas
        :param doc: SimpleDocTemplate
        """
        # Save the state of our canvas so we can draw on it
        c.saveState()
        self.header(c, doc, True)
        self.footer(c, doc)
        # Release the canvas
        c.restoreState()

    def header_footer_later_pages(self, c, doc) -> None:
        """
        First Page
        :param c: Canvas
        :param doc: SimpleDocTemplate
        """
        # Save the state of our canvas so we can draw on it
        c.saveState()
        self.header(c, doc, False)
        self.footer(c, doc)
        # Release the canvas
        c.restoreState()

    def write_content(self, elements) -> None:
        """
        write first page content
        :param elements:
        """
        styles = getSampleStyleSheet()
        styles.add(ParagraphStyle(name='MY_Justify', alignment=TA_JUSTIFY, leading=16))
        styles.add(ParagraphStyle(name='MY_Right', alignment=TA_RIGHT))
        styles.add(ParagraphStyle(name='MY_Center', alignment=TA_CENTER))
        styles.add(ParagraphStyle(name='MY_Head', alignment=TA_CENTER, fontSize=24, fontName="Helvetica-Bold"))

        elements.append(Spacer(1, 60))
        ptext = '<font size=8>Auftrag-Nr.: %s and Rechnung-Nr.: %s</font>' % (self._orderId, self._billingNr)
        elements.append(Paragraph(ptext, styles["Normal"]))
        elements.append(createBarcodeDrawing('Code128', value=self._orderId, height=40, width=120))

        elements.append(Spacer(1, 12))
        # FIXME: check self._type : should always be 2
        if self._type == '0':
            ptext = '<font size=12><b>Angebot</b></font>'
        elif self._type == '1':
            ptext = '<font size=12><b>Auftrag Bestätigung</b></font>'
        elif self._type == '2':
            ptext = '<font size=12><b>Lieferschein</b></font>'
        else:
            ptext = '<font size=12><b>Rechnung</b></font>'

        elements.append(Paragraph(ptext, styles["MY_Head"]))

        elements.append(Spacer(1, 12))
        ptext = '<font size=12>Sehr geehrter Herr %s,</font>' % self._customer_surname
        elements.append(Paragraph(ptext, styles["Normal"]))

        elements.append(Spacer(1, 12))
        ptext = '<font size=12>gemäß Ihrer Bestellung liefern wir wie folgt </font>'
        elements.append(Paragraph(ptext, styles["MY_Justify"]))

        elements.append(Spacer(1, 12))
        ptext = '<font size=12>Kunden-Nr.: %s / %s</font>' % (self._userId, self._userIdPlattform)
        elements.append(Paragraph(ptext, styles["MY_Right"]))

        elements.append(Spacer(1, 2))

        # loaded_json = json.loads(self._sold_items, strict=False)

        # items_json = loaded_json["items"]
        # list_collis = []
        # for x in items_json:
        #     if x["ean"] is not None and str(x["ean"]):
        #         ean = x["ean"]
        #     if x["stammbezeichnung"] is not None and str(x["stammbezeichnung"]):
        #         title = x["stammbezeichnung"]
        #     if x["packstueck"] is not None and str(x["packstueck"]):
        #         count = x["packstueck"]
        #     list_collis.append(stockup.Colli(ean, title, count))
        #
        # stockup_print = stockup.StockupPrintable(io.BytesIO(), list_collis)
        # aa = stockup_print.new_write_content()
        elements.append(self.table_articles())

        # shit begins
        elements.append(Spacer(1, 12))
        payment_info = """<font size=12>
            Zahlungsmethode: %s <br/>
            Zahlungsdatum: %s <br/>
            Bearbeitungszeit: %s Tage
        </font>
        """ % (self._payment_method, self._payment_date, self._working_days)
        elements.append(Paragraph(payment_info, styles["Normal"]))

        elements.append(Spacer(1, 12))
        shipping_info = """<font size=12>
            Versandart: %s <br/>
            Versanddatum: %s
        </font>
        """ % (self._shipping_method, self._shipping_date)
        elements.append(Paragraph(shipping_info, styles["Normal"]))

        elements.append(Spacer(1, 12))
        elements.append(self.talbe_comment())

        # shit ends

        elements.append(Spacer(1, 12))
        ptext = '<font size=12>Mit freundlichen Grüssen</font>'
        elements.append(Paragraph(ptext, styles["Normal"]))

        elements.append(Spacer(1, 48))
        if (self._is_sogood == "True"):
            ptext = '<font size=12>Ihr Sogood Team</font>'
        else:
            ptext = '<font size=12>Ihr Maimai24 Team</font>'
        elements.append(Paragraph(ptext, styles["Normal"]))
        elements.append(Spacer(1, 12))

    def talbe_comment(self):
        data = []
        data.append(["Memo:"])
        data.append([self._comment])
        data.append(["Rechnungsvermerk:"])
        data.append([self._invoice_comment])
        """
        Table for the memo part
        :return: Table
        """
        # Configure style and word wrap
        # which overrides the table style regarding fontSize
        s = getSampleStyleSheet()
        s = s["BodyText"]
        s.wordWrap = 'CJK'
        s.fontSize = 8
        s.alignment = TA_LEFT

        data_with_style = []
        for row in data:
            data_with_style_row = []
            for i in range(len(row)):
                data_with_style_row.append(Paragraph(row[i], s))
            data_with_style.append(data_with_style_row)

        t = Table(data_with_style, colWidths=[450])  # whole width is 450
        style = TableStyle([('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
                            ('BOX', (0, 0), (-1, -1), 0.25, colors.black),  # border of table
                            ])
        t.setStyle(style)
        return t

    def table_articles(self):
        """
        Runs demo demonstrating usage of Spreadsheet Tables.
        :return: Table
        """

        data = []
        data.append(["EAN", "Barcode", "Name", "Count"])
        loaded_json = json.loads(self._elements, strict=False)

        items_json = loaded_json["elements"]
        for x in items_json:
            row = []
            if x["ean"] is not None and str(x["ean"]):
                ean = x["ean"]
            row.append(ean)
            row.append(createBarcodeDrawing('Code128', value=ean, height=10, width=120))
            if x["name"] is not None and x["name"]:
                name_wrapped = textwrap.fill(x["name"], width=32)  # 将 name 按照 30 个字符进行换行
                row.append(name_wrapped)
            if x["count"] is not None and str(x["count"]):
                row.append(x["count"])
            data.append(row)

        # Configure style and word wrap
        # which overrides the table style regarding fontSize
        s = getSampleStyleSheet()
        s = s["BodyText"]
        s.wordWrap = 'CJK'
        s.fontSize = 8
        s.alignment = TA_LEFT

        s_right = getSampleStyleSheet()
        s_right = s_right["BodyText"]
        s_right.wordWrap = 'CJK'
        s_right.fontSize = 8
        s_right.alignment = TA_CENTER

        # 为第四列设置不同的样式（字体大小变为10）
        s_fourth_column = ParagraphStyle(name='FourthColumnStyle', fontSize=14, wordWrap='CJK', alignment=1)

        data_with_style = []
        for row_index,row in enumerate(data):
            data_with_style_row = []
            for i in range(len(row)):
                if row_index == 0:  # 第一行不应用样式，直接添加内容
                    data_with_style_row.append(row[i])
                else:
                    if i == 3:  # 针对第四列（索引为3）应用不同的样式
                        data_with_style_row.append(Paragraph(str(row[i]), s_fourth_column))
                    elif i == len(row) - 1:  # 针对最后一列应用右对齐样式
                        data_with_style_row.append(Paragraph(str(row[i]), s_right))
                    else:
                        # print("dupadupa %r" % (row[i]))
                        data_with_style_row.append(row[i])
            data_with_style.append(data_with_style_row)

        t = Table(data_with_style, colWidths=[83, 117, 200, 50])  # whole width is 450
        style = TableStyle([('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
                            ('BOX', (0, 0), (-1, -1), 0.25, colors.black),  # border of table
                            # ('ALIGN', (0, 0), (-1, 0), 'CENTER'),  # 标题行居中
                            ])
        t.setStyle(style)
        return t

    def do(self):
        """
        Entry method of the class
        :rtype: BytesIO
        """
        logger.info("deliverynote.py do()")

        doc = SimpleDocTemplate(self._buffer, pagesize=A4,
                                rightMargin=72, leftMargin=72,
                                topMargin=72, bottomMargin=72)
        elements = []
        self.write_content(elements)
        doc.build(elements, onFirstPage=self.header_footer_first_page, onLaterPages=self.header_footer_later_pages,
                  canvasmaker=NumberedCanvas)

        # Get the value of the BytesIO buffer and write it to the response.
        # comment the following lines if debug with __main__
        pdf = self._buffer.getvalue()
        self._buffer.close()
        return pdf
