ts2fable icon indicating copy to clipboard operation
ts2fable copied to clipboard

jsPDF: take 2

Open whitetigle opened this issue 7 years ago • 1 comments

Following my not so good latest issue on the topic, where I did not get the latest version (0.6.x) using yarn for an undertermined reason (one being: maybe I'm dumb) I decided to give the github version a go.

So using the generated .fs file, I tried to make jsPDF work but my first try was a miss. So after searching, I found how to make it work but I do need your confirmation to be sure I am not doing bad things here.

So the generated bindings give me:

// ts2fable 0.0.0
module rec Fable.Import.JsPDF
open System
open Fable.Core
open Fable.Import.JS
open Fable.Import.Browser

let [<Import("*","jspdf")>] jspdf: Jspdf.jsPDFStatic = jsNative //not working

module Jspdf =

    let [<Import("*","jspdf")>] jsPDF: jsPDFStatic = jsNative

    type [<AllowNullLiteral>] IExports =
        abstract jsPDF: jsPDFStatic

    type [<AllowNullLiteral>] jsPDF =
        abstract CapJoinStyles: obj option with get, set
        abstract version: string with get, set
        abstract ``internal``: obj with get, set
        abstract addPage: ?sizes: ResizeArray<float> -> jsPDF
        abstract setPage: n: float -> jsPDF
        abstract insertPage: beforePage: float -> jsPDF
        abstract movePage: targetPage: float * beforePage: float -> jsPDF
        abstract deletePage: n: float -> jsPDF
        abstract setDisplayMode: ?zoom: string * ?layout: string * ?pmode: string -> jsPDF
        abstract text: text: obj option * x: obj option * y: obj option * ?flags: obj option * ?angle: obj option * ?align: obj option -> jsPDF
        abstract lstext: text: string * x: float * y: float * spacing: float -> jsPDF
        abstract line: x1: float * y1: float * x2: float * y2: float -> obj option
        abstract clip: unit -> unit
        abstract lines: lines: obj option * x: obj option * y: obj option * ?scale: obj option * ?style: string * ?closed: bool -> jsPDF
        abstract rect: x: float * y: float * w: float * h: float * ?style: string -> jsPDF
        abstract triangle: x1: float * y1: float * x2: float * y2: float * x3: float * y3: float * style: string -> jsPDF
        abstract roundedRect: x: float * y: float * w: float * h: float * rx: float * ry: float * style: string -> jsPDF
        abstract ellipse: x: float * y: float * rx: float * ry: float * ?style: string -> jsPDF
        abstract circle: x: float * y: float * r: float * style: string -> jsPDF
        abstract setProperties: properties: obj option -> jsPDF
        abstract setFontSize: size: float -> jsPDF
        abstract setFont: ?fontName: string * ?fontStyle: string -> jsPDF
        abstract setFontStyle: style: string -> jsPDF
        abstract setFontType: style: string -> jsPDF
        abstract getFontList: unit -> obj option
        abstract addFont: postScriptName: string * fontName: string * fontStyle: string -> string
        abstract setLineWidth: width: float -> jsPDF
        abstract setDrawColor: ch1: U2<float, string> * ?ch2: float * ?ch3: float * ?ch4: float -> jsPDF
        abstract setFillColor: ch1: U2<float, string> * ?ch2: float * ?ch3: float * ?ch4: float -> jsPDF
        abstract setTextColor: ?r: float * ?g: float * ?b: float -> jsPDF
        abstract setLineCap: style: U2<string, float> -> jsPDF
        abstract setLineJoin: style: U2<string, float> -> jsPDF
        abstract output: ?``type``: string * ?options: obj option -> obj option
        abstract save: filename: string -> jsPDF
        /// jsPDF plugins below:
        ///
        ///   - AddHTML
        ///   - AddImage
        ///   - Annotations
        ///   - AutoPrint
        ///   - Canvas
        ///   - Cell
        ///   - Context2D
        ///   - FromHTML
        ///   - JavaScript
        ///   - PNG
        ///   - split_text_to_size
        ///   - SVG
        ///   - total_pages
        abstract addHTML: element: obj option * x: float * y: float * options: obj option * callback: Function -> jsPDF
        abstract addHTML: element: obj option * callback: Function -> jsPDF
        abstract color_spaces: obj option with get, set
        abstract decode: obj option with get, set
        abstract image_compression: obj option with get, set
        abstract sHashCode: str: string -> obj option
        abstract isString: ``object``: obj option -> bool
        abstract extractInfoFromBase64DataURI: dataURI: string -> ResizeArray<obj option>
        abstract supportsArrayBuffer: unit -> bool
        abstract isArrayBuffer: ``object``: obj option -> bool
        abstract isArrayBufferView: ``object``: obj option -> bool
        abstract binaryStringToUint8Array: binary_string: string -> Uint8Array
        abstract arrayBufferToBinaryString: buffer: obj option -> string
        abstract arrayBufferToBase64: arrayBuffer: ArrayBuffer -> string
        abstract createImageInfo: data: obj option * wd: obj option * ht: obj option * cs: obj option * bpc: obj option * imageIndex: float * alias: obj option * ?f: obj option * ?dp: obj option * ?trns: obj option * ?pal: obj option * ?smask: obj option -> obj option
        abstract addImage: ?imageData: obj option * ?format: obj option * ?x: float * ?y: float * ?w: float * ?h: float * ?alias: obj option * ?compression: obj option * ?rotation: obj option -> jsPDF
        abstract processJPEG: data: obj option * index: float * alias: obj option * ?compression: obj option * ?dataAsBinaryString: string -> obj option
        abstract processJPG: unit -> obj option
        abstract annotationPlugin: obj option with get, set
        abstract createAnnotation: options: obj option -> unit
        abstract link: x: float * y: float * w: float * h: float * options: obj option -> unit
        abstract textWithLink: text: string * x: float * y: float * options: obj option -> float
        abstract getTextWidth: text: string -> float
        abstract getLineHeight: unit -> float
        abstract autoPrint: unit -> jsPDF
        abstract canvas: obj with get, set
        abstract setHeaderFunction: func: Function -> unit
        abstract getTextDimensions: txt: string -> obj option
        abstract cellAddPage: unit -> unit
        abstract cellInitialize: unit -> unit
        abstract cell: x: float * y: float * w: float * h: float * txt: string * ln: float * align: string -> jsPDF
        abstract arrayMax: array: ResizeArray<obj option> * ?comparisonFn: Function -> float
        abstract table: x: float * y: float * data: obj option * headers: ResizeArray<string> * config: obj option -> jsPDF
        abstract calculateLineHeight: headerNames: ResizeArray<string> * columnWidths: ResizeArray<float> * model: ResizeArray<obj option> -> float
        abstract setTableHeaderRow: config: ResizeArray<obj option> -> unit
        abstract printHeaderRow: lineNumber: float * ?new_page: bool -> unit
        abstract context2d: obj with get, set
        abstract fromHTML: HTML: U2<string, HTMLElement> * x: float * y: float * ?settings: obj option * ?callback: Function * ?margins: obj option -> jsPDF
        abstract addJS: txt: string -> jsPDF
        abstract processPNG: imageData: obj option * imageIndex: float * alias: string * compression: obj option * dataAsBinaryString: string -> obj option
        abstract getCharWidthsArray: text: string * ?options: obj option -> ResizeArray<obj option>
        abstract getStringUnitWidth: text: string * ?options: obj option -> float
        abstract splitTextToSize: text: string * maxlen: float * ?options: obj option -> obj option
        abstract addSVG: svgtext: string * x: float * y: float * ?w: float * ?h: float -> jsPDF
        abstract putTotalPages: pageExpression: string -> jsPDF

    type [<AllowNullLiteral>] jsPDFStatic =
        [<Emit "new $0($1...)">] abstract Create: ?orientation: obj option * ?unit: string * ?format: string * ?compressPdf: float -> jsPDF

1st issue:

image

Here the correction is simple. I change

let [<Import("*","jspdf")>] jsPDF: JsPDF.IExports = jsNative

to

let [<Import("*","jspdf")>] IExports = jsNative

1st try:

open Fable.Import.JsPDF
let doc = jspdf.jsPDF.Create()
doc.text(!!(Some "Hello world!"), !!(Some 10.), !!(Some 10.)) |> ignore
doc.save("a4.pdf") |> ignore

but I get a webpack error: image

Solution:

After several tries I find that the use of the IExports Interface seems to give a wrong level of indirection. So I change

let [<Import("*","jspdf")>] jspdf: Jspdf.IExports = jsNative

module Jspdf =
    let [<Import("*","jspdf")>] jsPDF: JsPDF.IExports = jsNative

    type [<AllowNullLiteral>] IExports =
        abstract jsPDF: jsPDFStatic

to

let [<Import("*","jspdf")>] jspdf: Jspdf.jsPDFStatic = jsNative 

module Jspdf =

    let [<Import("*","jspdf")>] jsPDF: jsPDFStatic = jsNative

    type [<AllowNullLiteral>] IExports =
        abstract jsPDF: jsPDFStatic

which gives me a direct access to jsPDFStatic.

Then I change my calling code from

let doc = jspdf.jsPDF.Create()

to

let doc = jspdf.Create()

And it works.

Questions

Do I make things right? Is there another way to avoid to make theses changes? Do you need more details?

Thanks for your help!

whitetigle avatar Dec 30 '17 11:12 whitetigle

Thanks for the write-up.

ctaggart avatar Dec 30 '17 14:12 ctaggart