WHtml2docx.mjs

import path from 'path'
import process from 'process'
import get from 'lodash-es/get.js'
import isestr from 'wsemi/src/isestr.mjs'
import isearr from 'wsemi/src/isearr.mjs'
import ispnum from 'wsemi/src/ispnum.mjs'
import cdbl from 'wsemi/src/cdbl.mjs'
import str2b64 from 'wsemi/src/str2b64.mjs'
import execProcess from 'wsemi/src/execProcess.mjs'
import fsIsFile from 'wsemi/src/fsIsFile.mjs'


let fdSrv = path.resolve()


function isWindows() {
    return process.platform === 'win32'
}


/**
 * Html檔轉Docx檔
 *
 * @param {String} fpInHtml 輸入來源Html檔位置字串
 * @param {String} fpOutDocx 輸入轉出Docx檔位置字串
 * @param {Object} [opt={}] 輸入設定物件,預設{}
 * @param {String} [opt.fpInTemp='./src/tmp.docx'] 輸入Docx模板檔案位置字串,預設'./src/tmp.docx'
 * @param {Array|String} [opt.fontFamilies=['標楷體','Times New Roman']] 輸入轉出Docx時強制更改字型陣列或字串,陣列順序為變更順序,若有要覆寫字型得放後面。預設['標楷體','Times New Roman']
 * @param {String} [opt.imgRatioWidthMax=1] 輸入圖片最大寬度比例,值介於0至1,預設1
 * @param {String} [opt.imgRatioHeightMax=1] 輸入圖片最大高度比例,值介於0至1,預設1
 * @returns {Promise} 回傳Promise,resolve回傳成功訊息,reject回傳錯誤訊息
 * @example
 *
 * import w from 'wsemi'
 * import WHtml2docx from './src/WHtml2docx.mjs'
 * //import WHtml2docx from 'w-html2docx/src/WHtml2docx.mjs'
 * //import WHtml2docx from 'w-html2docx'
 *
 * async function test() {
 *
 *     let fpIn = `./test/ztmp.html`
 *     let fpOut = `./test/ztmp.docx`
 *     let opt = {
 *         imgRatioWidthMax: 0.5,
 *     }
 *
 *     let r = await WHtml2docx(fpIn, fpOut, opt)
 *     console.log(r)
 *     // => ok
 *
 *     w.fsDeleteFile(fpOut)
 *
 * }
 * test()
 *     .catch((err) => {
 *         console.log('catch', err)
 *     })
 *
 */
async function WHtml2docx(fpInHtml, fpOutDocx, opt = {}) {
    let errTemp = null

    //isWindows
    if (!isWindows()) {
        return Promise.reject('operating system is not windows')
    }

    //check
    if (!fsIsFile(fpInHtml)) {
        return Promise.reject(`fpInHtml[${fpInHtml}] does not exist`)
    }

    //fontFamilies
    let fontFamilies = get(opt, 'fontFamilies')
    if (isestr(fontFamilies)) {
        fontFamilies = [fontFamilies]
    }
    if (!isearr(fontFamilies)) {
        fontFamilies = ['標楷體', 'Times New Roman']
    }

    //imgRatioWidthMax
    let imgRatioWidthMax = get(opt, 'imgRatioWidthMax')
    if (!ispnum(imgRatioWidthMax)) {
        imgRatioWidthMax = 1
    }
    imgRatioWidthMax = cdbl(imgRatioWidthMax)

    //imgRatioHeightMax
    let imgRatioHeightMax = get(opt, 'imgRatioHeightMax')
    if (!ispnum(imgRatioHeightMax)) {
        imgRatioHeightMax = 1
    }
    imgRatioHeightMax = cdbl(imgRatioHeightMax)

    //fpInTemp
    let fpInTemp = get(opt, 'fpInTemp')
    if (!isestr(fpInTemp)) {

        //fnTmp
        let fnTmp = `tmp.docx`

        //fpInTemp
        if (true) {
            let fpTmpSrc = `${fdSrv}/src/${fnTmp}`
            let fpTmpNM = `${fdSrv}/node_modules/w-html2docx/src/${fnTmp}`
            if (fsIsFile(fpTmpSrc)) {
                fpInTemp = fpTmpSrc
            }
            else if (fsIsFile(fpTmpNM)) {
                fpInTemp = fpTmpNM
            }
            else {
                return Promise.reject(`can not find folder for ${fnTmp}`)
            }

        }

    }

    //轉絕對路徑
    fpInHtml = path.resolve(fpInHtml)
    fpInTemp = path.resolve(fpInTemp)
    fpOutDocx = path.resolve(fpOutDocx)

    //fnExe
    let fnExe = `htmlToDocx.exe`

    //fdExe
    let fdExe = ''
    if (true) {
        let fdExeSrc = `${fdSrv}/src/`
        let fdExeNM = `${fdSrv}/node_modules/w-html2docx/src/`
        if (fsIsFile(`${fdExeSrc}${fnExe}`)) {
            fdExe = fdExeSrc
        }
        else if (fsIsFile(`${fdExeNM}${fnExe}`)) {
            fdExe = fdExeNM
        }
        else {
            return Promise.reject('can not find folder for html2docx')
        }
    }
    // console.log('fdExe', fdExe)

    //prog
    let prog = `${fdExe}${fnExe}`
    // console.log('prog', prog)

    //inp
    let inp = {
        fpInSrc: fpInHtml,
        fpInTemp,
        fpOut: fpOutDocx,
        fontFamilies: ['標楷體', 'Times New Roman'],
        imgRatioWidthMax,
        imgRatioHeightMax,
    }
    // console.log('inp', inp)

    //input to b64
    let cInput = JSON.stringify(inp)
    let b64Input = str2b64(cInput)
    // console.log('b64Input', b64Input)

    //execProcess
    await execProcess(prog, b64Input)
        .catch((err) => {
            console.log('execProcess catch', err)
            errTemp = err.toString()
        })

    //check
    if (errTemp) {
        return Promise.reject(errTemp)
    }

    // //check
    // if (!isestr(output)) {
    //     return Promise.reject(`output[${cstr(output)}] is not an effective string`)
    // }

    return 'ok'
}


export default WHtml2docx