JXL (jxl.jar) 不支援 autoSizeColumn,針對以中文為主的報表,可統計每欄最大字元寬度(中文佔 2 個字元單位),手動設定欄寬達到近似自適應效果。
\u4e00-\u9fa5,每字佔 2 寬度單位。sheet.setColumnView(colIndex, width) 設定。import java.io.File;
import java.util.*;
import java.util.regex.*;
import jxl.Workbook;
import jxl.write.*;
public class ExcelBestColumn {
public static void main(String[] args) throws Exception {
// 模擬資料:兩列兩行
List<String> row1 = Arrays.asList("最適合列寬", "這個基本可以實現");
List<String> row2 = Arrays.asList("Best Column Width", "Haha");
List<List<String>> data = Arrays.asList(row1, row2);
WritableWorkbook book = Workbook.createWorkbook(new File("t.xls"));
WritableSheet sheet = book.createSheet("測試", 0);
writeDataToSheet(sheet, data);
book.write();
book.close();
}
public static void writeDataToSheet(WritableSheet sheet, List<List<String>> data) throws Exception {
int colCount = data.get(0).size();
int[] bestWidth = new int[colCount]; // 記錄各欄最大寬度
// 寫入資料並同步統計寬度
for (int i = 0; i < data.size(); i++) {
List<String> row = data.get(i);
for (int j = 0; j < row.size(); j++) {
String cell = row.get(j);
sheet.addCell(new Label(j, i, cell));
// 計算顯示寬度:中文算 2,其他算 1
int width = cell.length() + getChineseCount(cell);
if (bestWidth[j] < width) bestWidth[j] = width;
}
}
// 套用欄寬
for (int i = 0; i < bestWidth.length; i++) {
sheet.setColumnView(i, bestWidth[i]);
}
}
/** 統計字串中中文字符數量 */
public static int getChineseCount(String str) {
int count = 0;
Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
Matcher m = p.matcher(str);
while (m.find()) count++;
return count;
}
}
| 場景 | 效果 | 說明 |
|---|---|---|
| 純中文/中英混雜報表 | 優 | 中文等寬特性明顯,統計準確 |
| 純英文大小寫混合 | 良 | 字母寬度差異小(i vs W),近似可用 |
| 含特殊符號、全形/半形混雜 | 一般 | 符號寬度差異大,難以精準統計 |
| 數字金額欄位 | 優 | 等寬字體下數字寬度一致 |
autoSizeColumn 並可獲取字體度量資訊。java.awt.FontMetrics) 計算實際像素寬度,再換算為 JXL 寬度單位 (1/256 字符寬度)。<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>