下载openoffice:
进入program目录后,继续执行(按原句执行不要更改)
soffice -headless -accept=”socket,host=127.0.0.1,port=8100;urp;” -nofirststartwizard
注意:excel行太长 openoffice解决不了 我在下篇博客会有解决方案
1、pom文件加入
<dependency>
<groupId>com.artofsolving</groupId>
<artifactId>jodconverter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.openoffice</groupId>
<artifactId>jurt</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.openoffice</groupId>
<artifactId>ridl</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.openoffice</groupId>
<artifactId>juh</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.openoffice</groupId>
<artifactId>unoil</artifactId>
<version>3.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.artofsolving.jodconverter/jodconverter-core -->
<dependency>
<groupId>org.artofsolving.jodconverter</groupId>
<artifactId>jodconverter-core</artifactId>
<version>3.0-beta-4</version>
</dependency>
2、转换的工具类
/**
* @author gezc30201
* @description 利用jodconverter(基于OpenOffice服务)将文件(* .doc 、 * .docx 、 * .ppt)转化为html格式或者pdf格式,
* * .xls、*.xlsx 列太多 会有折叠问题
* @date 2020/5/8
*/
@Slf4j
public class Doc2PdfUtil {
/**
*@description 转成pdf流
* @param fileEnd
* @param fileInput
* @return java.io.InputStream
* @author gezc30201
* @date 2020/5/8
*/
public static InputStream doc2pdf(String fileEnd, InputStream fileInput) throws Exception {
String fileType = "";
Integer colWidth = 0;
if (DocEnum.XLSX.getSuffix().equals(fileEnd) || DocEnum.XLS.getSuffix().equals(fileEnd)) { //xlsx格式的文件转成xls处理
ByteArrayOutputStream baos = getByteArrayStream(fileInput); //把输入流转成输出数组的方法
fileInput = new ByteArrayInputStream(baos.toByteArray());
InputStream streamClon = new ByteArrayInputStream(baos.toByteArray());
colWidth = getColumnWidth(streamClon, fileEnd); //获取excel有数据的列数
fileType = DocEnum.XLS.getSuffix();
} else if (DocEnum.DOCX.getSuffix().equals(fileEnd)) { //docx格式的文件转成doc处理
fileType = DocEnum.DOC.getSuffix();
} else {
fileType = fileEnd;
}
try {
ByteArrayOutputStream pdfstream =convert(fileInput,fileType, colWidth);
byte[] outbytes = pdfstream.toByteArray();
InputStream pdfInput = new BufferedInputStream(new ByteArrayInputStream(pdfstream.toByteArray()));//把pdf流转成输入流
pdfstream.flush();
pdfstream.close();
return pdfInput;
} catch (Exception e) {
log.error(ExceptionUtils.getTrace(e));
throw new RuntimeException();
}finally{
if (fileInput!=null){
fileInput.close();
}
}
}
/**
*@description 描述
* @param fileEnd
* @param inbytes
* @return byte[]
* @author gezc30201
* @date 2020/5/9
*/
public static byte[] doc2pdf(String fileEnd, byte[] inbytes) throws Exception {
String fileType = "";
Integer colWidth = 0;
if (DocEnum.DOCX.getSuffix().equals(fileEnd)) { //docx格式的文件转成doc处理
fileType = DocEnum.DOC.getSuffix();
} else {
fileType = fileEnd;
}
ByteArrayInputStream fileInput=null;
try {
fileInput=new ByteArrayInputStream(inbytes);
ByteArrayOutputStream pdfstream =convert(fileInput,fileType, colWidth);
byte[] outbytes = pdfstream.toByteArray();
pdfstream.close();
return outbytes;
}catch (Exception e) {
log.error(ExceptionUtils.getTrace(e));
throw new RuntimeException();
}finally{
if (fileInput!=null){
fileInput.close();
}
}
}
/**
*@description 连接openoffice服务器进行转换
* @param fileInput
* @param fileType
* @param colWidth
* @return java.io.ByteArrayOutputStream
* @author gezc30201
* @date 2020/5/9
*/
private static ByteArrayOutputStream convert( InputStream fileInput, String fileType, int colWidth) {
OpenOfficeConnection connection =null;
ByteArrayOutputStream pdfstream=null;
try {
connection = new SocketOpenOfficeConnection(8100);
MyDocumentConverter converter = new MyDocumentConverter(connection, fileType, colWidth); //使用StreamOpenOfficeDocumentConverter可以转07版的
DefaultDocumentFormatRegistry formatReg = new DefaultDocumentFormatRegistry(); //jar包里的类
DocumentFormat inputFormat = formatReg.getFormatByFileExtension(fileType); //源文件的格式
DocumentFormat pdfFormat = formatReg.getFormatByFileExtension("pdf"); //转成的格式
pdfstream = new ByteArrayOutputStream(); //保存转成pdf的流的数组
converter.convert(fileInput, inputFormat, pdfstream, pdfFormat); //将文件流转换成pdf流
}catch (Exception e){
log.error(ExceptionUtils.getTrace(e));
throw new RuntimeException();
}finally {
connection.disconnect();
}
return pdfstream;
}
/**
*@description 描述
* @param fileInput
* @return java.io.ByteArrayOutputStream
* @author gezc30201
* @date 2020/5/9
*/
private static ByteArrayOutputStream getByteArrayStream(InputStream fileInput) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = fileInput.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
baos.flush();
return baos;
}
/**
*@description 获得行的宽度
* @param fileInput
* @param fileEnd
* @return java.lang.Integer
* @author gezc30201
* @date 2020/5/9
*/
private static Integer getColumnWidth(InputStream fileInput, String fileEnd) throws Exception {
Workbook workBook = ExcelUtil.getWorkBook(fileInput, fileEnd);
int colWidth = 0;
if (workBook != null) {
Sheet sheet = workBook.getSheetAt(0);
if (sheet != null) {
int colNum = sheet.getRow(1).getPhysicalNumberOfCells();
for (int i = 0; i < colNum; i++) {
colWidth += sheet.getColumnWidth(i);
}
}
}
workBook.close();
return colWidth;
}
/* public static void excel2pdf(InputStream fromFileInputStream, String toFilePath, String type) throws Exception {
InputStream is = doc2pdf(type, fromFileInputStream);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String timesuffix = sdf.format(new Date());
File htmlOutputFile = new File(toFilePath + File.separatorChar +timesuffix+ ".pdf");
if (htmlOutputFile.exists()) {
htmlOutputFile.delete();
}
htmlOutputFile.createNewFile();
FileOutputStream fos = new FileOutputStream(htmlOutputFile);
byte[] b = new byte[1024];
int length;
while ((length = is.read(b)) > 0){
fos.write(b,0,length);
}
is.close();
fos.close();
}
public static void main(String[] args) throws Exception {
File file = null;
FileInputStream fileInputStream = null;
file = new File("D:\\test\\test.docx");
fileInputStream = new FileInputStream(file);
excel2pdf(fileInputStream, "D:\\test\\", "docx");
}*/
}
openoffice的配置类:
/***
*@description openoffice :DOC转pdf 默认用A4 修改不用A4 excel用ExcelToPdfUtil解决折叠问题
* @author gezc30201
* @date 2020/5/8
*/
@Slf4j
public class MyDocumentConverter extends StreamOpenOfficeDocumentConverter {
public MyDocumentConverter(OpenOfficeConnection connection){
super(connection);
}
private String fileType;
private Integer colWidth;
public MyDocumentConverter(OpenOfficeConnection connection, String fileType, Integer colWidth) {
super(connection);
this.colWidth = colWidth;
this.fileType = fileType;
}
public final static Size A4, A3, A2, A1;
public final static Size B4, B3, B2, B1;
public final static Size PPTREPORT;
public final static int KA4= 21000;
public final static int KA3=29700;
public final static int KA2=42000;
public final static int KA1=60000;
static {
A4 = new Size(21000, 29700);
A3 = new Size(29700, 42000);
A2 = new Size(42000, 59400);
A1 = new Size(60000, 90000);
B4 = new Size(25000, 35300);
B3 = new Size(35300, 50000);
B2 = new Size(50000, 70700);
B1 = new Size(70700, 100000);
PPTREPORT = new Size(25000, 29700);
}
@Override
protected void refreshDocument(XComponent document) {
super.refreshDocument(document);
// The default paper format and orientation is A4 and portrait. To
// change paper orientation
// re set page size
XPrintable xPrintable = (XPrintable) UnoRuntime.queryInterface(XPrintable.class, document);
PropertyValue[] printerDesc = new PropertyValue[3];
printerDesc[0] = new PropertyValue();
printerDesc[0].Name = "PaperFormat";
printerDesc[0].Value = PaperFormat.USER;
// Paper Size
printerDesc[1] = new PropertyValue();
printerDesc[1].Name = "PaperSize";
/***
*
* excel的调整不管用 最多只能到A3
*
*/
if (DocEnum.XLS.getSuffix().equals(fileType)||DocEnum.XLSX.getSuffix().equals(fileType)) {
if (colWidth <= KA4) {
printerDesc[1].Value = A4;
} else if (colWidth > KA4 && colWidth <= KA3) {
printerDesc[1].Value = A3;
} else if (colWidth > KA3 && colWidth <= KA2) {
printerDesc[1].Value = A2;
} else if (colWidth > KA2 && colWidth <= KA1) {
printerDesc[1].Value = A1;
} else {
printerDesc[1].Value = A4;
}
/**
* ppt用A4的话 会有一点看不到 所以用A3(有空白)
*/
}else if (DocEnum.PPT.getSuffix().equals(fileType)||DocEnum.PPTX.getSuffix().equals(fileType)){
printerDesc[1].Value = A3;
} else {
printerDesc[1].Value = A4;
}
printerDesc[2] = new PropertyValue();
printerDesc[2].Name = "Pages";
printerDesc[2].Value = 2;
try {
xPrintable.setPrinter(printerDesc);
} catch (Exception e) {
log.error(ExceptionUtils.getTrace(e));
}
}
}
枚举类:
/**
*@description 文件后缀
* @author gezc30201
* @date 2020/5/9
*/
public enum DocEnum {
/**
* 文件后缀
*/
DOC(".doc","doc"),
DOCX(".docx","docx"),
PPT(".ppt","ppt"),
PPTX(".pptx","pptx"),
XLS(".xls","xls"),
XLSX(".xlsx","xlsx"),
PDF(".pdf","pdf");
private String pointSuffix;
private String suffix;
DocEnum(String pointSuffix, String suffix) {
this.pointSuffix = pointSuffix;
this.suffix = suffix;
}
public String getPointSuffix() {
return pointSuffix;
}
public String getSuffix() {
return suffix;
}
}
excel兼容工具类:
/**
*@description 描述
* @author gezc30201
* @date 2020/5/8
*/
@Slf4j
public class ExcelUtil {
public static Workbook getWorkBook(InputStream in, String fileEnd) throws Exception {
Workbook workbook = null;
try {
if (DocEnum.XLS.getSuffix().equals(fileEnd)) { //根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
workbook = new HSSFWorkbook(in);
} else if (DocEnum.XLSX.getSuffix().equals(fileEnd)) { //2007 及2007以上
workbook = new XSSFWorkbook(in); //2003
}
} catch (Exception e) {
log.error(ExceptionUtils.getTrace(e));
return null;
}
return workbook;
}
}
controller:
@GetMapping("/previewAttach")
public void previewAttach(HttpServletResponse response, @RequestParam(value = "attach_id") String attachId) {
DownloadAttach downloadAttach = sysAttachService.downloadAttach(attachId).getResult();
if (downloadAttach == null || downloadAttach.getBytes() == null) {
log.warn("附件获取为空。附件id:" + attachId.replaceAll("[\r\n]", ""));
throw new BaseBizException("-1", "附件不存在");
}
/*if (!".pdf".equals(downloadAttach.getFileSuffix())){6
throw new BaseBizException("-1", "只有PDF可以预览");
}*/
if (!DocEnum.PDF.getPointSuffix().equals(downloadAttach.getFileSuffix())&&!DocEnum.XLS.getPointSuffix().equals(downloadAttach.getFileSuffix())&&!DocEnum.XLSX.getPointSuffix().equals(downloadAttach.getFileSuffix())){
try {
downloadAttach.setBytes(Doc2PdfUtil.doc2pdf(downloadAttach.getFileSuffix().substring(1),downloadAttach.getBytes()));
} catch (Exception e) {
log.error(ExceptionUtils.getTrace(e));
throw new BaseBizException("-1", "openoffice服务连接不上或者转换pdf失败");
}
}
if (DocEnum.XLS.getPointSuffix().equals(downloadAttach.getFileSuffix())||DocEnum.XLSX.getPointSuffix().equals(downloadAttach.getFileSuffix())){
try {
downloadAttach.setBytes(ExcelToPdfUtil.excel2pdf(downloadAttach.getBytes()));
} catch (IOException e) {
log.error(ExceptionUtils.getTrace(e));
throw new BaseBizException("-1", "excel转换pdf失败");
}
}
OutputStream os = null;
try {
response.setHeader("content-length", String.valueOf(downloadAttach.getBytes().length));
// 预览
response.setContentType("application/pdf;charset=utf-8");
response.setHeader("content-disposition", "inline;filename=" +
java.net.URLEncoder.encode(downloadAttach.getFileName(), "UTF-8"));
os = response.getOutputStream();
//os.write(downloadAttach.getBytes(),0,downloadAttach.getBytes().length);
int lens = downloadAttach.getBytes().length;
int flag = 0;
while (lens > 0){
os.write(Arrays.copyOfRange(downloadAttach.getBytes(),flag * DOWNLOAD_LENS,(lens > DOWNLOAD_LENS) ? (flag + 1) * DOWNLOAD_LENS : (flag * DOWNLOAD_LENS + lens)));
flag ++;
log.info(flag);
lens -= DOWNLOAD_LENS;
}
} catch (Exception e) {
log.error("预览附件报错。附件id:" + attachId.replaceAll("[\r\n]", ""));
log.error(ExceptionUtils.getTrace(e));
} finally {
if (os != null) {
try {
os.flush();
os.close();
} catch (IOException e) {
log.error(ExceptionUtils.getTrace(e));
}
}
}
}