JSA复制图片到剪切板再嵌入单元格

曲折的做法,原始的写法。根据需要自行完善。

function copyPic(){
    Range("A1:A4").Select()
    Selection.CopyPicture();
}

function Clipboard(){
    console.clear();
    copyPic()

    let DIB = ffi.Struct([
        { name: "biSize", type: "uint32" },
        { name: "biWidth", type: "uint32" },
        { name: "biHeight", type: "uint32" },
        { name: "biPlanes", type: "uint16" },
        { name: "biBitCount", type: "uint16" },
        { name: "biCompression", type: "uint32" },
        { name: "biSizeImage", type: "uint32" },
        { name: "biXPelsPerMeter", type: "uint32" },
        { name: "biYPelsPerMeter", type: "uint32" },
        { name: "biClrUsed", type: "uint32" },
        { name: "biClrImportant", type: "uint32" }
    ])
    //let dib = new DIB(); //暂时没用


    const {GlobalAlloc,GlobalLock,GlobalUnlock,RtlMoveMemory} = ffi.LoadLibrary('kernel32.dll', {

            GlobalAlloc: { returnType: "pointer", parameters: ["uint32", "uint32"] },            
            GlobalLock: { returnType: "pointer", parameters: ["uint32"] },            
            GlobalUnlock: { returnType: "bool", parameters: ["uint32"] },            
            RtlMoveMemory: { returnType: "void", parameters: ["pointer", "pointer", "uint32"] }
            
    });

    const {CountClipboardFormats,EnumClipboardFormats,OpenClipboard,CloseClipboard,GetClipboardData,
        EmptyClipboard,SetClipboardData,IsClipboardFormatAvailable} = ffi.LoadLibrary("user32.dll",{
        
            CountClipboardFormats: { returnType: "uint32", parameters: []},
            EnumClipboardFormats:{ returnType: "uint32", parameters: ["uint32"]},
            OpenClipboard:{ returnType: "bool", parameters: ["pointer"]},
            CloseClipboard:{ returnType: "bool", parameters: []},
            GetClipboardData:{ returnType: "uint32", parameters: ["uint32"]},
            EmptyClipboard: { returnType: "bool", parameters: [] },
            SetClipboardData: { returnType: "pointer", parameters: ["uint32", "pointer"] },
             IsClipboardFormatAvailable : { returnType: "bool", parameters: ["uint32"] }
                 
    })


        let count = CountClipboardFormats();
        
        console.log("剪切板格式总数:" + count);
        
        OpenClipboard(null);        
        
        let hClipboard = GetClipboardData(49465);
        
        console.log("图像数据句柄:" +hClipboard )

        let mdib = GlobalLock(hClipboard);
        //Console.log("图像大小:" + mdib.Read("uint8",48)); //从偏移0开始读取4字节数据 内存中为 89 50 4E 47 读出来后转换为 47 4E 50 89 => 1196314761
        
        //la = hexToArr(numToHex(mdib.Read("uint32",32)));
        let bytes = 32;
        
        for(let index = 1;index<5;index++){
            let la = hexToArr(numToHex(mdib.Read("uint32",bytes + 1)));
            console.log(JSON.stringify(la))
            if(la.length == 1){
                bytes+=13
                break;
            }else{
            
            off = la[0]+la[1]*256+la[2]*65536 + la[3]*16777216;
            Console.log("块大小:" + (off));
            bytes+=(off+12)
            
            }
            Console.log("指针位置:" + (bytes));    
        }
        
        Console.log("图像大小:" + (bytes));
        let str=''
        let byteArray =[]
        for(let i=0;i<bytes;i++){
            byteArray.push(mdib.Read("uint8",i))
            
        }
        //console.log(JSON.stringify(byteArray))
        let binaryString = ''
        byteArray.forEach(i => binaryString += String.fromCharCode(i))
        let pngpath = "D:/test.png"
        FileSystem.writeAsBinaryString(pngpath,binaryString)
                
        Range("E2").RangeEx.InsertCellPicture(pngpath);
        
        try{
            //Range("E2").RangeEx.InsertCellPictureRaw(binaryString); //不知道具体实现参数
        }
        catch{
            console.log(1)
            GlobalUnlock(hClipboard);
        }
        
        
        //Console.log("图像大小:" + mdib.DerefString());
        
        GlobalUnlock(hClipboard);

//49161,13,1,49411,49804,49171,16,7,0  //单纯文本

// 和下一行对应: 49161,        49800,                    49465,    49801,                49171 //复制一个单元格,格式为图片
//               DataObject,Kingsoft Shapes Tag,    Png,    Et Embed Pic Formats,OLE Private DataView

//49161 == DataObject
// 49171 == OLE Private DataView
//13 == Unicode Text Format
//1 == Text
// 49465 == PNG ?  C1 39




let nextFormat = EnumClipboardFormats(0);

console.log("第一个剪切板格式:"+nextFormat)

let available = IsClipboardFormatAvailable(49465)

console.log("剪切板格式是否存在:"+available)

CloseClipboard();


}

function numToHex(arg) {
    try {
        let a = arg.toString(16).toUpperCase();
        return a.length % 2 == 1 ? "0" + a : a;
    } catch (e) {
        console.warn("数字转16进制出错:", e);
    }
}

function hexToArr(str) {
    // hex字符串长度通常都是2的倍数,但为了放止意外,判断一下长度,不是2的倍数就在最前面补0
    if (str.length % 2) str = "0" + str
    let arr=[]
    for (let i = 0; i < str.length; i+=2) {
        let a=parseInt(str.slice(i,i+2),16)
        arr.push(a)
    }
    return arr
}

黑龙江省
浏览 170
收藏
4
分享
4 +1
1
+1
全部评论 1
 
麻辣君
点赞学习
· 云南省
回复