Установка ширины столбца в Apache POI
Я пишу инструмент в Java, используя Apache POI API для преобразования XML в MS Excel. В моем XML-вводе я получаю ширину столбца в точках. Но API Apache POI имеет немного странную логику для установки ширины столбца на основе размера шрифта и т.д. (См. API docs)
Есть ли формула для преобразования точек в ширину, как ожидалось в Excel? Кто-нибудь сделал это раньше?
Существует метод setRowHeightInPoints()
, хотя:( но не для столбца.
P.S.: Входной XML находится в формате ExcelML, который мне нужно преобразовать в MS Excel.
Ответы
Ответ 1
К сожалению, есть только функция setColumnWidth (int columnIndex, int width) из class Sheet
; в котором ширина представляет собой количество символов стандартного шрифта (первый шрифт в рабочей книге), если ваши шрифты меняются, вы не можете его использовать.
Объясняется, как рассчитать ширину в зависимости от размера шрифта. Формула:
width = Truncate([{NumOfVisibleChar} * {MaxDigitWidth} + {5PixelPadding}] / {MaxDigitWidth}*256) / 256
Вы всегда можете использовать autoSizeColumn(int column, boolean useMergedCells)
после ввода данных в Sheet
.
Ответ 2
Пожалуйста, обратите внимание на использование autoSizeColumn()
. Его можно использовать без проблем на небольших файлах, но, пожалуйста, обратите внимание, что метод вызывается только один раз (в конце) для каждого столбца и не вызывается внутри цикла, что не имеет смысла.
Пожалуйста, избегайте использования autoSizeColumn()
в больших файлах Excel. Метод создает проблему с производительностью.
Мы использовали его в файле 110k rows/11 columns. Для вычисления всех столбцов метод взял ~ 6 м.
Для более подробной информации смотрите: Как ускорить автоматизацию столбцов в apache POI?
Ответ 3
Вы также можете использовать методы, упомянутые в этом блоге: Получение информации о высоте и высоте ячейки из Excel с помощью Apache POI. Это может решить вашу проблему.
Копировать и вставить из этого блога:
static public class PixelUtil {
public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256;
public static final short EXCEL_ROW_HEIGHT_FACTOR = 20;
public static final int UNIT_OFFSET_LENGTH = 7;
public static final int[] UNIT_OFFSET_MAP = new int[] { 0, 36, 73, 109, 146, 182, 219 };
public static short pixel2WidthUnits(int pxs) {
short widthUnits = (short) (EXCEL_COLUMN_WIDTH_FACTOR * (pxs / UNIT_OFFSET_LENGTH));
widthUnits += UNIT_OFFSET_MAP[(pxs % UNIT_OFFSET_LENGTH)];
return widthUnits;
}
public static int widthUnits2Pixel(short widthUnits) {
int pixels = (widthUnits / EXCEL_COLUMN_WIDTH_FACTOR) * UNIT_OFFSET_LENGTH;
int offsetWidthUnits = widthUnits % EXCEL_COLUMN_WIDTH_FACTOR;
pixels += Math.floor((float) offsetWidthUnits / ((float) EXCEL_COLUMN_WIDTH_FACTOR / UNIT_OFFSET_LENGTH));
return pixels;
}
public static int heightUnits2Pixel(short heightUnits) {
int pixels = (heightUnits / EXCEL_ROW_HEIGHT_FACTOR);
int offsetWidthUnits = heightUnits % EXCEL_ROW_HEIGHT_FACTOR;
pixels += Math.floor((float) offsetWidthUnits / ((float) EXCEL_ROW_HEIGHT_FACTOR / UNIT_OFFSET_LENGTH));
return pixels;
}
}
Поэтому, когда вы хотите получить ширину и высоту ячейки, вы можете использовать это для получения значения в пикселях, значения примерно равны.
PixelUtil.heightUnits2Pixel((short) row.getHeight())
PixelUtil.widthUnits2Pixel((short) sh.getColumnWidth(columnIndex));
Ответ 4
С Scala есть приятный Wrapper spoiwo
Вы можете сделать это так:
Workbook(mySheet.withColumns(
Column(autoSized = true),
Column(width = new Width(100, WidthUnit.Character)),
Column(width = new Width(100, WidthUnit.Character)))
)
Ответ 5
Я ответил на мою проблему с шириной по умолчанию для всех столбцов и ячеек, как показано ниже:
int width = 15; // Where width is number of caracters
sheet.setDefaultColumnWidth(width);