pythonhtmlclipboardpywin32rtf

SetClipboardData can't write any data


I am trying to write HTML to the clipboard as rich text, but it doesn't work. What did I do wrong? I tried running html_to_clipboard separately, but the clipboard is empty. SetClipboardData does not insert any text into it. However, copy_to_clipboard can write text successfully. Is there a step missing?

Note: If I comment out

    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(CF_HTML, text.encode('utf-8'))

and add print(clipboard_data.decode('utf-8')), it can capture the content of the rich text properly, but SetClipboardData does not work and can't write any data...

import win32con
import win32clipboard,win32

text = '''Version:1.0
    StartHTML:0000000128
    EndHTML:0000000371
    StartFragment:0000000128
    EndFragment:0000000371
    SourceURL:about:blank
    <html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"></head><body><div style="background-color:#1e1f22;color:#bcbec4"><pre style="font-family:'JetBrains Mono',monospace;font-size:9.8pt;">xt()</pre></div></body></html> '''
result = 'Some Text'

def copy_to_clipboard():
    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardText(result, win32clipboard.CF_TEXT)
    clipboard_data = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT)
    if clipboard_data.decode('utf-8') == result:
        print('Copied to clipboard successfully')
    else:
        print('Failed to copy to clipboard')
    win32clipboard.CloseClipboard()

def html_to_clipboard():
    CF_HTML = win32clipboard.RegisterClipboardFormat("HTML Format")

    win32clipboard.OpenClipboard(0)
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(CF_HTML, bytearray(text, 'utf-8'))
    clipboard_data = win32clipboard.GetClipboardData(CF_HTML)
    # print(clipboard_data.decode('utf-8'))
    if clipboard_data.decode('utf-8') == text:
        print('Copied HTML to clipboard successfully')
    else:
        print('Failed to copy HTML to clipboard')
    win32clipboard.CloseClipboard()

if __name__ == '__main__':
    # copy_to_clipboard()
    html_to_clipboard()

it return:

C:\ProgramData\anaconda3\envs\python311\python.exe C:\Users\Administrator\Personal_scripts\pythonProject\temp.py 
Copied HTML to clipboard successfully

But the clipboard is blank in Win+V, and it can't paste any text.

Python: 3.11

OS:Windows10 Enterprise 21H2

Code Editor:Pycharm community

I tried: https://gist.github.com/Erreinion/6691093

But it don't work either. The clipboard is blank in Win+V too.


Solution

  • Refer to the third-party library "klembord" that supports rich text input. I adjusted the code and added SetClipboardText(unicode_text, CF_UNICODETEXT). The clipboard successfully reads the desired content. Win+V will display unicode_text instead of RTF, even though it displays as blank. If unicode_text is blank, I able to paste RTF content correctly in a RTF editor, but unable to paste unicode_text.

    from re import search
    from bs4 import BeautifulSoup
    import win32clipboard
    
    text = '''Version:0.9
    StartHTML:0000000105
    EndHTML:0000000272
    StartFragment:0000000141
    EndFragment:0000000236
    <html>
    <body>
    <!--StartFragment--><p style="font-family: Consolas, Monaco, monospace;" id="20240514135730-37ivg0u" updated="20240514135730"><span data-type="code">loop</span></p>
    <!--EndFragment-->
    </body>
    </html>'''
    
    
    def html_to_clipboard():
        CF_HTML = win32clipboard.RegisterClipboardFormat("HTML Format")
    
        win32clipboard.OpenClipboard(0)
        win32clipboard.EmptyClipboard()
        win32clipboard.SetClipboardData(CF_HTML, text.encode('utf-8'))
        unicode_text ='loop'
        win32clipboard.SetClipboardText(unicode_text, win32clipboard.CF_UNICODETEXT)
        clipboard_data = win32clipboard.GetClipboardData(CF_HTML)
        print("HTML:\n"+clipboard_data.decode('utf-8'))
        clipboard_data = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT)
        print("TEXT:\n"+clipboard_data)
    
    def get_clipboard():
        CF_HTML = win32clipboard.RegisterClipboardFormat("HTML Format")
    
        win32clipboard.OpenClipboard(0)
        clipboard_data = win32clipboard.GetClipboardData(CF_HTML)
        clipboard_data=BeautifulSoup(search('<!--StartFragment-->([\\s\\S]+)<!--EndFragment-->|<html>([\\s\\S]+)</html>',clipboard_data.decode('utf-8')).group(0),'lxml').prettify()
        print("HTML:\n"+clipboard_data)
        clipboard_data = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT)
        print("TEXT:\n"+clipboard_data)
        win32clipboard.CloseClipboard()
    
    html_to_clipboard()
    # get_clipboard()