Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Openpyxl Worksheets have limited functionality when it comes to doing row or column level operations. The only properties a Worksheet has that relates to rows/columns are the properties <code>row_dimensions</code> and <code>column_dimensions</code>, which store "RowDimensions" and "ColumnDimensions" objects for each row and column, respectively. These dictionaries are also used in function like <code>get_highest_row()</code> and <code>get_highest_column()</code>.</p> <p>Everything else operates on a cell level, with Cell objects being tracked in the dictionary, <code>_cells</code> (and their style tracked in the dictionary <code>_styles</code>). Most functions that look like they're doing anything on a row or column level are actually operating on a range of cells (such as the aforementioned <code>append()</code>).</p> <p>The simplest thing to do would be what you suggested: create a new sheet, append your header row, append your new data rows, append your old data rows, delete the old sheet, then rename your new sheet to the old one. Problems that may be presented with this method is the loss of row/column dimensions attributes and cell styles, unless you specifically copy them, too.</p> <p>Alternatively, you could create your own functions that insert rows or columns.</p> <p>I had a large number of <em>very</em> simple worksheets that I needed to delete columns from. Since you asked for explicit examples, I'll provide the function I quickly threw together to do this:</p> <pre><code>from openpyxl.cell import get_column_letter def ws_delete_column(sheet, del_column): for row_num in range(1, sheet.get_highest_row()+1): for col_num in range(del_column, sheet.get_highest_column()+1): coordinate = '%s%s' % (get_column_letter(col_num), row_num) adj_coordinate = '%s%s' % (get_column_letter(col_num + 1), row_num) # Handle Styles. # This is important to do if you have any differing # 'types' of data being stored, as you may otherwise get # an output Worksheet that's got improperly formatted cells. # Or worse, an error gets thrown because you tried to copy # a string value into a cell that's styled as a date. if adj_coordinate in sheet._styles: sheet._styles[coordinate] = sheet._styles[adj_coordinate] sheet._styles.pop(adj_coordinate, None) else: sheet._styles.pop(coordinate, None) if adj_coordinate in sheet._cells: sheet._cells[coordinate] = sheet._cells[adj_coordinate] sheet._cells[coordinate].column = get_column_letter(col_num) sheet._cells[coordinate].row = row_num sheet._cells[coordinate].coordinate = coordinate sheet._cells.pop(adj_coordinate, None) else: sheet._cells.pop(coordinate, None) # sheet.garbage_collect() </code></pre> <p>I pass it the worksheet that I'm working with, and the column number I want deleted, and away it goes. I know it isn't exactly what you wanted, but I hope this information helped!</p> <p><strong>EDIT:</strong> Noticed someone gave this another vote, and figured I should update it. The co-ordinate system in Openpyxl experienced some changes sometime in the passed couple years, introducing a <code>coordinate</code> attribute for items in <code>_cell</code>. This needs to be edited, too, or the rows will be left blank (instead of deleted), and Excel will throw an error about problems with the file. This works for Openpyxl 2.2.3 (untested with later versions)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload