Python -- 将字符串添加到剪贴板,将以正确的格式粘贴到 Excel(即,分成 rows/columns)

Python -- Adding string to clipboard that will paste to Excel in proper format (i.e., separated into rows/columns)

我已经看到了这个问题的一些答案,但是在 VBA 和 C# 中——在 python 中什么都没有。 在 python 3 中,我正在尝试执行以下操作:

  1. 用适当的"excel"格式
  2. 为变量分配一串值
  3. 然后将此变量复制到剪贴板
  4. 然后用户应该能够手动 CTRL+V(粘贴)此字符串到 excel 并将其分开到正确的 row/column 位置。

我在我的项目中同时使用了 tkinter 和 openpyxl,通过测试我得到了一些结果,但这不是我想要的。我得到的最接近的是下面。

# If I first go into excel, 
# and copy a few columns within a single row with different data in them, 
# then I run the following code: 

import tkinter as tk
root = tk.Tk()
paste = root.clipboard_get()

print(paste)

# Then I manually copy the print output to the clipboard,
# and then go back to excel and paste, 
# excel gives the following warning message:
# "The data you're pasting isn't the same size as your selection.  do you want to paste anyways?"
# And after pressing OK, it seems as though the data is pasted properly. 

没关系,打印(粘贴)字符串可能会帮助我为要生成的字符串的初始变量创建适当的格式,但我需要一个不会导致 Excel 的解决方案让这个警告标志每次都弹出。

如果有人能对此提供一些见解,我将不胜感激。此外,解决方案需要通过 python 而不是通过修改 Excel。其次,解决方案不是 appending/writing 将数据直接 Excel (通过 Openpyxl 等),而是将数据以适当的格式(我正在使用 Excel 2016 ).

谢谢!!


编辑:

我也尝试过使用用户 kichik here 提供的 "ctypes solution"。

为了使这个解决方案更容易使用,我下载了一个名为 "InsideClipboard" 的应用程序,它可以让我轻松查看剪贴板 "copies" 数据所在的每种格式的格式 ID。

使用 kichik 的 ctype 解决方案,我检查了手动复制剪贴板中存储的不同格式的打印输出是否可以让我手动 CTRL+V 到原始格式的 Excel,但是失败了。原来的"copy"是多列字符串在单行字符串中来自Excel,而手动"paste"将各个格式返回到excel中,将所有字符串保存到单个单元格(创建多行数据的 HTML 格式除外——也是错误的)。不同的格式包括 CF_LOCALE (16)、CF_TEXT (1)、CF_OEMTEXT (7)、CF_UNICODETEXT (13) 和 HTML 格式 (49384) .

所以,仍然:没有解决方案。


编辑2:

我意识到我可以在 python 中创建字符串,在字符串之间按下实际的制表符,而不是使用 \t,并且它可以创建一个字符串,将数据放入不同的列粘贴到 Excel.

时的一行

此外,我意识到如果我 CTRL+V 直接进入 Excel(不在行标题上),在我想粘贴数据的实际行上,我不再得到 Excel "warning message"。因此,使用此解决方法可能会奏效。如果没有人有任何意见,那么这种简单的方法可能就足够了。

但是,我希望能够简单地单击行标题而不是第一个相关行单元格来粘贴数据,而不会出现 Excel 警告弹出窗口。仍然欢迎提出想法,最好通过 python 完成所有工作(无需修改 Excel,因为应用程序可能 运行 在不同的 Windows OS个人电脑)。

所以:可能的简单解决方案,但并不完美。


编辑 3:

所以我想出了一个基于Edit2的解决方案。如果 Excel 在工作计算机上作为应用程序打开,Excel "warning" 弹出窗口仍然会出现;但是,如果 Excel 文件是通过在线处理器打开和编辑的,则用户可以突出显示行标题并粘贴,而不会生成 Excel "warning" 弹出窗口。这在我的特定情况下有效,尽管更好的解决方案是让复制的数据在任何情况下都不生成 Excel "warning" 弹出窗口。无论如何,如果没有人知道如何单独通过 python 来防止 Excel 警告弹出,那么我仍然可以使用这种方法。

这是我的解决方案(注意长字符串中的空格实际上是'tabs'):

import pyperclip

# t variables are defined prior to the below code
# note: the "   " parts in the data string are actually tabs

data = t1 + "   " + t2 + "  " + "   " + t3 + "  " + t4 + "  " + t5 + "  " + t6 + "  " + t7 + "  "  + "  " + "t8"  + "   "  + "  "  + "  "  + "  "  + "  "  + "  " + t9 + "  " + t10 + " " + t11 + " " + t12 + " "  + "  "  + "  "  + "  "  + "  "  + "  " + t13

pyperclip.copy(data)
print("clipboard:", data)

# now manually pressing CTRL+V while inside Excel (online processor) will
# paste the various t variables in the appropriate cells designated by 
# the "   " tabs in between.  Of note, this works for columns of a single
# row as I didn't need multiple rows of data for my task.

下面是在 tkinter 中创建 5 行 3 列条目网格的代码。按复制按钮将条目的内容作为制表符/换行符分隔的字符串复制到剪贴板,然后可以将其粘贴到 excel.

import tkinter as tk
from tkinter import ttk

ROWS = 5
COLS = 3

root = tk.Tk()

rows = []  # Container for Entry widgets.

# Create and grid the Entry widgets.
for row in range( ROWS ):
    temp = []
    for col in range( COLS ):
        temp.append( ttk.Entry(root, width = 10 ))
        temp[-1].grid( row = row, column = col )
    rows.append( temp )

def entries_to_lists( rows ):
    list_out = []
    for row in rows:
        temp = []
        for col in row:
            temp.append( col.get() )
        list_out.append( temp )
    return list_out

def string_out( rows ):
    """ Prepares a '\t', '\n' separated string to send to the clipboard. """
    out = []
    for row in rows:
        out.append( '\t'.join( row ))  # Use '\t' (tab) as column seperator.
    return '\n'.join(out)              # Use '\n' (newline) as row seperator.

def do_copy():
    data = entries_to_lists( rows )
    root.clipboard_clear()
    root.clipboard_append( string_out( data ))     # Paste string to the clipboard
    root.update()   # The string stays on the clipboard after the window is closed

ttk.Button( text = "  Copy  ", command= do_copy ).grid( column = 1 )
# Button to trigger the copy action.

root.title("Copy to Excel Test")
root.geometry("400x200+10+10")
root.mainloop()

这在 Windows 10 中复制到 Excel 2013,没有警告消息。

string_out 将从任何字符串列表列表中生成一个合适的字符串,一个二维列表。