Maven依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>net.sf.jxls</groupId>
<artifactId>jxls-core</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.poi.xwpf.converter.pdf-gae</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.aspose.words</groupId>
<artifactId>aspose-words</artifactId>
<version>19.5</version>
</dependency>
aspose需要下载jar包(需要可以联系博主)
license.xml(去除aspose的水印),放在resource目录下即可
<License>
<Data>
<Products>
<Product>Aspose.Total for JavaProduct>
<Product>Aspose.Words for JavaProduct>
Products>
<EditionType>EnterpriseEditionType>
<SubscriptionExpiry>20991231SubscriptionExpiry>
<LicenseExpiry>20991231LicenseExpiry>
<SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7SerialNumber>
Data>
<Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=Signature>
License>
部分关键代码
调用生成word方法
//data替换固定文本集合,2博主自用,int[]模板内有多少个表格
generatePdf(data, 2, new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8}, enPdfPath, LanguageTypeEnum.en_US.getType(), 0);
获取模板并调用生成word方法
private void generateZhCNPdf(PdfDTO pdfDTO) {
Map<String, Object> data = pdfDTO.getData();
File file;
InputStream is;
file = new File(this.getClass().getResource("/template/temp.docx").getPath());
is = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/temps.docx");
List<List<String[]>> mapList = pdfDTO.getMapList();
int[] placeList = pdfDTO.getPlaceList();
String pdfPath = pdfDTO.getPdfPath();
String str = pdfPath.substring(0, pdfPath.lastIndexOf("/"));
//判断文件夹是否存在
File file1 = new File(str);
if (!file1.exists() && !file1.isDirectory()) {
file1.mkdirs();
}
new Thread() {
@SneakyThrows
@Override
public void run() {
extractedZhCn(data, file, is, mapList, placeList, pdfPath);
}
}.start();
}
生成word
//临时存储文件,本地运行,需要注释该行
FileUtils.copyInputStreamToFile(is, file);
Thread.sleep(1000);
//data固定填充内容map集合,file.getPath()模板地址,mapList需要循环填充表格的内容 placelist创建多少个表格的int[]
CustomXWPFDocument doc = WorderToNewWordUtils.changWord(file.getPath(), data, mapList, placeList);
//生成临时word文档
FileOutputStream fopts = new FileOutputStream(pdfPath + ".docx");
doc.write(fopts);
fopts.close();
changWord方法(填充数据)
CustomXWPFDocument document = null;
try {
//获取docx解析对象
document = new CustomXWPFDocument(POIXMLDocument.openPackage(inputUrl));
//解析替换文本段落对象
WorderToNewWordUtils.changeText(document, textMap);
//解析替换表格对象
WorderToNewWordUtils.changeTable(document, textMap, mapList,placeList);
} catch (IOException e) {
e.printStackTrace();
}
return document;
changText()
public static void changeText(CustomXWPFDocument document, Map<String, Object> textMap){
//获取段落集合
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
paragraph.setAlignment(ParagraphAlignment.LEFT);
//判断此段落时候需要进行替换
String text = paragraph.getText();
if(checkText(text)){
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
// 替换模板原来位置
run.setText(changeValue(run.text(), textMap), 0);
}
}
}
}
/**
* 判断文本中时候包含$
* @param text 文本
* @return 包含返回true,不包含返回false
*/
public static boolean checkText(String text){
boolean check = false;
if(text.indexOf("$")!= -1){
check = true;
}
return check;
}
/**
* 匹配传入信息集合与模板
* @param value 模板需要替换的区域
* @param textMap 传入信息集合
* @return 模板需要替换区域信息集合对应值
*/
public static String changeValue(String value, Map<String, Object> textMap) {
Set<Map.Entry<String, Object>> textSets = textMap.entrySet();
for (Map.Entry<String, Object> textSet : textSets) {
// 匹配模板与替换值 格式${key}
String key = textSet.getKey() ;
if (value.indexOf(key) != -1) {
if(textSet.getValue() != null){
value = textSet.getValue().toString();
}
}
}
// 模板未匹配到区域替换为空
if (checkText(value)) {
value = "";
}
return value;
}
changeTable(填充循环数据)
public static void changeTable(CustomXWPFDocument document, Map<String, Object> textMap, List<List<String[]>> mapList,int[] placeList){
//获取表格对象集合
List<XWPFTable> tables = document.getTables();
//循环所有需要进行替换的文本,进行替换
for (int i = 0; i < tables.size(); i++) {
XWPFTable table = tables.get(i);
if(checkText(table.getText())){
List<XWPFTableRow> rows = table.getRows();
System.out.println("简单表格替换:"+rows);
//遍历表格,并替换模板
eachTable(document,rows, textMap);
}
}
int index=0;
//操作word中的表格
for (int i = 0; i < tables.size(); i++) {
//只处理行数大于等于2的表格,且不循环表头
XWPFTable table = tables.get(i);
if(placeList != null){
if(placeList[index]==i){
List<String[]> list = mapList.get(index);
//第二个表格使用daList,插入数据
if (null != list && 0 < list.size()){
insertTable(table, null,list,2);
List<Integer[]> indexList = startEnd(list);
for (int c=0;c<indexList.size();c++){
//合并行
mergeCellVertically(table,0,indexList.get(c)[0]+1,indexList.get(c)[1]+1);
}
}
if(placeList.length > (index+1)){
index++;
}
}
}
}
}
/**
* 合并行
* @param table
* @param col 需要合并的列
* @param fromRow 开始行
* @param toRow 结束行
*/
public static void mergeCellVertically(XWPFTable table, int col, int fromRow, int toRow) {
for(int rowIndex = fromRow; rowIndex <= toRow; rowIndex++){
CTVMerge vmerge = CTVMerge.Factory.newInstance();
vmerge.setVal(STMerge.RESTART);
XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
CTTcPr tcPr = cell.getCTTc().getTcPr();
if (tcPr != null) {
tcPr.setVMerge(vmerge);
} else {
tcPr = CTTcPr.Factory.newInstance();
tcPr.setVMerge(vmerge);
cell.getCTTc().setTcPr(tcPr);
}
}
}
/**
* 遍历表格
* @param rows 表格行对象
* @param textMap 需要替换的信息集合
*/
public static void eachTable(CustomXWPFDocument document, List<XWPFTableRow> rows , Map<String, Object> textMap){
for (XWPFTableRow row : rows) {
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
//判断单元格是否需要替换
if(checkText(cell.getText())){
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
paragraph.setAlignment(ParagraphAlignment.LEFT);
paragraph.setKeepNext(false);
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
Object ob = changeValue(run.toString(), textMap);
if (ob instanceof String){
run.setText((String)ob,0);
}else if (ob instanceof Map){
run.setText("",0);
Map pic = (Map)ob;
int width = Integer.parseInt(pic.get("width").toString());
int height = Integer.parseInt(pic.get("height").toString());
int picType = getPictureType(pic.get("type").toString());
byte[] byteArray = (byte[]) pic.get("content");
ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);
try {
String blipId = document.addPictureData(byteInputStream,picType);
document.addPictureToRun(run, blipId, document.getAllPictures().size() -1,width , height);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
}
}
/**
* 为表格插入数据,行数不够添加新行
* @param table 需要插入数据的表格
* @param tableList 第四个表格的插入数据
* @param daList 第二个表格的插入数据
* @param type 表格类型:1-第一个表格 2-第二个表格 3-第三个表格 4-第四个表格
*/
public static void insertTable(XWPFTable table, List<String> tableList,List<String[]> daList,Integer type){
if (2 == type){
//设置表格边框样式
table.setLeftBorder(XWPFTable.XWPFBorderType.NONE , 0 , 0 ,"FFFFFF");
table.setRightBorder(XWPFTable.XWPFBorderType.NONE , 0 , 0 ,"FFFFFF");
table.setTopBorder(XWPFTable.XWPFBorderType.NONE , 0 , 0 ,"FFFFFF");
table.setInsideVBorder(XWPFTable.XWPFBorderType.NONE , 0 , 0 , "FFFFFF");
table.setInsideHBorder(XWPFTable.XWPFBorderType.SINGLE,0,0,"BEBEBE");
table.setBottomBorder(XWPFTable.XWPFBorderType.SINGLE,0,0,"BEBEBE");
//创建行和创建需要的列
for(int i = 1; i < daList.size(); i++){
//添加一个新行
XWPFTableRow row = table.insertNewTableRow(1);
for(int k=0; k<daList.get(0).length;k++){
row.createCell();//根据String数组第一条数据的长度动态创建列
row.setCantSplitRow(true);
}
}
//创建行,根据需要插入的数据添加新行,不处理表头
for(int i = 0; i < daList.size(); i++){
//合计行是否加粗
boolean blods = false;
List<XWPFTableCell> cells = table.getRow(i+1).getTableCells();
for(int j = 0; j < cells.size(); j++){
//是否加粗合并
boolean blod = false;
//固定列是否合并
boolean mell = false;
XWPFTableCell cell02 = cells.get(j);
// 设置水平居中,需要ooxml-schemas包支持
CTTc cttc = cell02.getCTTc();
CTTcPr ctPr = cttc.addNewTcPr();
ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);
// 修改字体大小
String s = daList.get(i)[j];
//获取 CTP
CTP ctP = (cttc.sizeOfPArray() == 0) ?
cttc.addNewP() : cttc.getPArray(0);
//getParagraph(ctP) 获取 XWPFParagraph
XWPFParagraph par = cell02.getParagraph(ctP);
CTP ctp = par.getCTP();
CTPPr ctpPr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();
//设置行间距
CTSpacing spacing = ctpPr.isSetSpacing()? ctpPr.getSpacing() : ctpPr.addNewSpacing();
spacing.setAfter(BigInteger.valueOf(0));
spacing.setBefore(BigInteger.valueOf(0));
//注意设置行距类型为 EXACT
spacing.setLineRule(STLineSpacingRule.EXACT);
//1磅数是20
spacing.setLine(BigInteger.valueOf(360));
par.setAlignment(ParagraphAlignment.THAI_DISTRIBUTE);
par.setKeepNext(false);
Map<Object,Object> map = new HashMap<Object,Object>(1,0.70f);
Map<Object,Object> map1 = new HashMap<Object,Object>(map);
//par.setBorderTop();
//XWPFRun 设置格式
XWPFRun run = par.createRun();
//加粗
run.setBold(true);
run.setFontSize(10);
run.setText(s);
//设置字体
CTFonts font = run.getCTR().addNewRPr().addNewRFonts();
//中文
font.setEastAsia("思源");
// ASCII
font.setAscii("Poppins");
font.setCs("Poppins");
font.setHAnsi("Poppins");
if (run.getText(0) != null && run.getText(0).contains("\n")) {
String[] lines = run.getText(0).split("\n");
if (lines.length > 0) {
run.setText(lines[0], 0);
for (int n = 1; n < lines.length; n++) {
run.addBreak();
run.setText(lines[n]);
}
}
}
//合并列(合并的列内需要有值,会保留前一列的值)
mergeCellsHorizontal(table, i + 1, j + 2, j + 3);
//设置靠齐方向
par.setAlignment(ParagraphAlignment.RIGHT);
}
}
}else if (4 == type){
//插入表头下面第一行的数据
for(int i = 0; i < tableList.size(); i++){
XWPFTableRow row = table.createRow();
List<XWPFTableCell> cells = row.getTableCells();
cells.get(0).setText(tableList.get(i));
}
}
}
//合并列方法
public static void mergeCellsHorizontal(XWPFTable table, int row, int startCell, int endCell) {
for (int i = startCell; i <= endCell; i++) {
XWPFTableCell cell = table.getRow(row).getCell(i);
if (i == startCell) {
// The first merged cell is set with RESTART merge value
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
}
else {
// Cells which join (merge) the first one, are set with CONTINUE
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
}
}
}
转换pdf
public static boolean zhCnWordToPDF(String sfileName, String toFileName) {
if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
return false;
}
FileOutputStream os = null;
try {
long old = System.currentTimeMillis();
File file = new File(toFileName); // 新建一个空白pdf文档
os = new FileOutputStream(file);
Document document= new Document(sfileName); // Address是将要被转化的word文档
Document document1 = new Document(toFileName);
//设置pdf字体
DocumentBuilder documentBuilder = new DocumentBuilder(document1);
documentBuilder.getFont().setName("思源黑体 CN");
documentBuilder.getFont().setNameAscii("Poppins");
documentBuilder.getFont().setNameOther("Poppins");
TableCollection tables = document.getFirstSection().getBody().getTables();
for (Table table : tables) {
RowCollection rows = table.getRows();
table.setAllowAutoFit(false);
for (Row row : rows) {
CellCollection cells = row.getCells();
for (Cell cell : cells) {
CellFormat cellFormat = cell.getCellFormat();
cellFormat.setFitText(false);
cellFormat.setWrapText(true);
}
}
}
document.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
// EPUB, XPS, SWF 相互转换
long now = System.currentTimeMillis();
System.out.println("pdf转换成功,共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时
} catch (Exception e) {
e.printStackTrace();
return false;
}finally {
if (os != null) {
try {
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
验证license
public static boolean getLicense() {
boolean result = false;
InputStream is = null;
try {
Resource resource = new ClassPathResource("/license.xml");
is = resource.getInputStream();
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}