Apache POI 5:在 word table 单元格中设置超链接
Apache POI 5 : Set hyperlinks in word table cell
我有一个 JDBC 结果集,我试图在 docx 文件的 table 中显示它。结果集中的一列是 link 。我能够解析 link 但无法在单元格中将其设置为 hyperlink 。我经历了多个 SO 问题,但无法实现。正在生成文件,但 link 列显示为空白。
// Set Custom Font Size
static void setFontSize(XWPFTableCell cell, int size) {
for (XWPFParagraph paragraph : cell.getParagraphs()) {
for (XWPFRun run : paragraph.getRuns()) {
run.setFontSize(size);
}
}
}
// Set table cell as link
static void setLink(XWPFTableCell cell, String text, String link,int size) {
for (XWPFParagraph paragraph : cell.getParagraphs()) {
XWPFRun run = paragraph.createHyperlinkRun(link);
run.setText(text);
run.setUnderline(UnderlinePatterns.SINGLE);
run.setColor("0000FF");
run.setFontSize(size);
}
}
public Void extractData(ResultSet rs) throws SQLException, DataAccessException {
ResultSetMetaData rsmd = rs.getMetaData();
int columnsNumber = rsmd.getColumnCount();
XWPFDocument document = new XWPFDocument();
// Set page orientation
CTDocument1 ctDocument = document.getDocument();
CTBody ctBody = ctDocument.getBody();
CTSectPr ctSectPr = (ctBody.isSetSectPr()) ? ctBody.getSectPr() : ctBody.addNewSectPr();
CTPageSz ctPageSz = (ctSectPr.isSetPgSz()) ? ctSectPr.getPgSz() : ctSectPr.addNewPgSz();
ctPageSz.setOrient(STPageOrientation.LANDSCAPE);
// set paper size A3
ctPageSz.setW(java.math.BigInteger.valueOf(Math.round(16.5 * 1440))); // 16.5 inches
ctPageSz.setH(java.math.BigInteger.valueOf(Math.round(11.7 * 1440))); // 11.7 inches
// Creating Table with 1 row and as many columns as in the result set
XWPFTable table = document.createTable(1, columnsNumber);
// Get header Row
XWPFTableRow header = table.getRow(0);
// Set header columns
for (int col = 0; col < columnsNumber; col++) {
header.getCell(col).setText(rsmd.getColumnLabel(col + 1));
// header.getCell(col).getCTTc().addNewTcPr().addNewShd().setFill("0394fc");
setFontSize(header.getCell(col), 6);
}
// Set data rows
while (rs.next()) {
XWPFTableRow desRow = table.createRow();
for (int col = 0; col < columnsNumber; col++) {
final var value = rs.getObject(col + 1);
String v = value == null ? "" : value.toString();
if (v.startsWith("<a")) {
Document doc = Jsoup.parse(v);
Elements rows = doc.getElementsByTag("a");
String text = "";
for (Element element : rows) {
text = element.text();
String href = element.attr("href").trim();
String encURL = "";
encURL = href.replaceAll(" ", "%20");
setLink(desRow.getCell(col), text, encURL,6);
}
} else {
desRow.getCell(col).setText(v);
setFontSize(desRow.getCell(col), 6);
}
}
}
table.removeBorders();
XWPFStyles styles = document.createStyles();
XWPFStyle style;
style = createTableStyle(styles, "ListTableStyle");
table.setStyleID(style.getStyleId());
try {
document.write(os);
document.close();
} catch (IOException e) {
log.error("Error occurred: {0}", e);
}
return null;
}
您的 setLink
方法假定 XWPFTableCell
已经有段落。但新创建的空 XWPFTableCell
s 并非如此。因此 for (XWPFParagraph paragraph : cell.getParagraphs())
正文中的代码行将无法到达,因为 cell.getParagraphs()
returns 是空的 List
.
您的 setLink
方法最好如下所示:
...
static void setLink(XWPFTableCell cell, String text, String link) {
XWPFParagraph paragraph = cell.addParagraph();
XWPFRun run = paragraph.createHyperlinkRun(link);
run.setText(text);
run.setUnderline(UnderlinePatterns.SINGLE);
run.setColor("0000FF");
}
...
字体大小的设置不应该在setLink
里面完成。为此,您有 setFontSize
。此方法还假定 XWPFTableCell
已经有段落。但这是真的,因为它是在将文本设置到单元格后调用的。
所以这两种方法都可以这样调用:
...
XWPFTableCell desCell = desRow.getCell(col);
setLink(desCell, text, encURL);
setFontSize(desCell, 6);
...
我有一个 JDBC 结果集,我试图在 docx 文件的 table 中显示它。结果集中的一列是 link 。我能够解析 link 但无法在单元格中将其设置为 hyperlink 。我经历了多个 SO 问题,但无法实现。正在生成文件,但 link 列显示为空白。
// Set Custom Font Size
static void setFontSize(XWPFTableCell cell, int size) {
for (XWPFParagraph paragraph : cell.getParagraphs()) {
for (XWPFRun run : paragraph.getRuns()) {
run.setFontSize(size);
}
}
}
// Set table cell as link
static void setLink(XWPFTableCell cell, String text, String link,int size) {
for (XWPFParagraph paragraph : cell.getParagraphs()) {
XWPFRun run = paragraph.createHyperlinkRun(link);
run.setText(text);
run.setUnderline(UnderlinePatterns.SINGLE);
run.setColor("0000FF");
run.setFontSize(size);
}
}
public Void extractData(ResultSet rs) throws SQLException, DataAccessException {
ResultSetMetaData rsmd = rs.getMetaData();
int columnsNumber = rsmd.getColumnCount();
XWPFDocument document = new XWPFDocument();
// Set page orientation
CTDocument1 ctDocument = document.getDocument();
CTBody ctBody = ctDocument.getBody();
CTSectPr ctSectPr = (ctBody.isSetSectPr()) ? ctBody.getSectPr() : ctBody.addNewSectPr();
CTPageSz ctPageSz = (ctSectPr.isSetPgSz()) ? ctSectPr.getPgSz() : ctSectPr.addNewPgSz();
ctPageSz.setOrient(STPageOrientation.LANDSCAPE);
// set paper size A3
ctPageSz.setW(java.math.BigInteger.valueOf(Math.round(16.5 * 1440))); // 16.5 inches
ctPageSz.setH(java.math.BigInteger.valueOf(Math.round(11.7 * 1440))); // 11.7 inches
// Creating Table with 1 row and as many columns as in the result set
XWPFTable table = document.createTable(1, columnsNumber);
// Get header Row
XWPFTableRow header = table.getRow(0);
// Set header columns
for (int col = 0; col < columnsNumber; col++) {
header.getCell(col).setText(rsmd.getColumnLabel(col + 1));
// header.getCell(col).getCTTc().addNewTcPr().addNewShd().setFill("0394fc");
setFontSize(header.getCell(col), 6);
}
// Set data rows
while (rs.next()) {
XWPFTableRow desRow = table.createRow();
for (int col = 0; col < columnsNumber; col++) {
final var value = rs.getObject(col + 1);
String v = value == null ? "" : value.toString();
if (v.startsWith("<a")) {
Document doc = Jsoup.parse(v);
Elements rows = doc.getElementsByTag("a");
String text = "";
for (Element element : rows) {
text = element.text();
String href = element.attr("href").trim();
String encURL = "";
encURL = href.replaceAll(" ", "%20");
setLink(desRow.getCell(col), text, encURL,6);
}
} else {
desRow.getCell(col).setText(v);
setFontSize(desRow.getCell(col), 6);
}
}
}
table.removeBorders();
XWPFStyles styles = document.createStyles();
XWPFStyle style;
style = createTableStyle(styles, "ListTableStyle");
table.setStyleID(style.getStyleId());
try {
document.write(os);
document.close();
} catch (IOException e) {
log.error("Error occurred: {0}", e);
}
return null;
}
您的 setLink
方法假定 XWPFTableCell
已经有段落。但新创建的空 XWPFTableCell
s 并非如此。因此 for (XWPFParagraph paragraph : cell.getParagraphs())
正文中的代码行将无法到达,因为 cell.getParagraphs()
returns 是空的 List
.
您的 setLink
方法最好如下所示:
...
static void setLink(XWPFTableCell cell, String text, String link) {
XWPFParagraph paragraph = cell.addParagraph();
XWPFRun run = paragraph.createHyperlinkRun(link);
run.setText(text);
run.setUnderline(UnderlinePatterns.SINGLE);
run.setColor("0000FF");
}
...
字体大小的设置不应该在setLink
里面完成。为此,您有 setFontSize
。此方法还假定 XWPFTableCell
已经有段落。但这是真的,因为它是在将文本设置到单元格后调用的。
所以这两种方法都可以这样调用:
...
XWPFTableCell desCell = desRow.getCell(col);
setLink(desCell, text, encURL);
setFontSize(desCell, 6);
...