导入jar
com.aspose
aspose-words
13.9.0.0
com.aspose
aspose-cells
8.5.2
commons-io
commons-io
2.6
org.apache.pdfbox
pdfbox
2.0.8
org.apache.pdfbox
fontbox
2.0.8
controller层
从本地读取文件信息
public class WordToPngController {
public static void main(String[] args) {
File file = new File(“D:\我的资料\网盘资料\30 Linux性能优化实战\pdf\03 基础篇:经常说的 CPU 上下文切换是什么意思?(上).pdf”);
try {
FileInputStream fis = new FileInputStream(file);
AsposeUtil.parseFileToBase64_PNG(fis,10,“txt”);
} catch (Exception e) {
e.printStackTrace();
}
}
}
之前在网上搜了好多资料都是从本地读取一个文件,现在附上从服务器上读取的流信息
public void onlinePreview(HttpServletResponse resp, @RequestParam(name = “fileId”) String fileId) {
InputStream file = null;
FileInfoPO po = fileInfoService.selectByPk(fileId,FileInfoPO.class);
try {
if (po != null) {
String fileUrl = po.getRemoteUrl();
//获取流信息
file = fileInfoService.getInPutStreamFromEcm(fileUrl);
//转成数组
byte[] bytes = AsposeUtil.parseFileToBase64_PNG(file,po.getFileType());
//转成base64返回
String base64 = Base64.getEncoder().encodeToString(bytes);
OutputStream os = resp.getOutputStream();
os.write(base64.getBytes(“UTF-8”));
os.flush();
os.close();
}
} catch (Exception e) {
logger.error(“文档转图片失败:{}”,e);
}
}
工具类
public class AsposeUtil {
private static Logger logger = LoggerFactory.getLogger(AsposeUtil.class);
private static List wordList = new ArrayList();
private static List exclelList = new ArrayList();
private static List pdfList = new ArrayList();
static {
wordList.add(“TXT”);
wordList.add(“DOC”);
wordList.add(“DOCX”);
exclelList.add(“XLS”);
exclelList.add(“XLSX”);
pdfList.add(“PDF”);
pdfList.add(“PDFX”);
}
public static byte[] parseFileToBase64_PNG(InputStream inputStream, String ext) throws Exception {
List bufferedImages = new ArrayList();
BufferedImage image = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
if (wordList.contains(ext.toUpperCase())) {//word转图片
logger.info("word转图片开始...");
bufferedImages = wordToImg(inputStream);
image = mergeImage(false, bufferedImages);
ImageIO.write(image, "png", baos);//写入流中
logger.info("word转图片结束...");
} else if(exclelList.contains(ext.toUpperCase())){//excel转图片
logger.info("excel转图片开始...");
baos = ConvertToImage.ConvertToImage(inputStream);//写入流中
logger.info("excel转图片结束...");
} else if(pdfList.contains(ext.toUpperCase())){//PDF转图片
logger.info("PDF转图片开始...");
bufferedImages = pdfToImg(inputStream);
image = mergeImage(false, bufferedImages);
ImageIO.write(image, "png", baos);//写入流中
logger.info("PDF转图片结束...");
}
byte[] bytes = baos.toByteArray();//转换成字节
//写到本地磁盘上
// File file = new File(“D:/a.jpg”);
// FileOutputStream fos = new FileOutputStream(file);
// fos.write(bytes);
// fos.flush();
// fos.close();
baos.close();
inputStream.close();
return bytes;
}
/**
* @Description: pdf文件转换图片
*/
private static List pdfToImg(InputStream inputStream) throws Exception {
PDDocument doc = PDDocument.load(inputStream);
PDFRenderer renderer = new PDFRenderer(doc);
ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG);
options.setPrettyFormat(true);
options.setUseAntiAliasing(true);
options.setUseHighQualityRendering(true);
int pageCount = doc.getNumberOfPages();
List imageList = new ArrayList<>();
for (int i = 0; i < pageCount; i++) {
BufferedImage bufferedImage = renderer.renderImageWithDPI(i, 144);
imageList.add(bufferedImage);
}
return imageList;
}
/**
* @Description: 验证aspose.word组件是否授权:无授权的文件有水印标记
*/
public static boolean isWordLicense() {
boolean result = false;
try {
ClassPathResource resource = new ClassPathResource("static/wordLicense.xml");
InputStream inputStream = resource.getInputStream();
com.aspose.words.License license = new com.aspose.words.License();
license.setLicense(inputStream);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* @Description: word文件转换图片
*/
private static List wordToImg(InputStream inputStream) throws Exception {
if (!isWordLicense()) {
return null;
}
try {
long old = System.currentTimeMillis();
Document doc = new Document(inputStream);
ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG);
options.setPrettyFormat(true);
options.setUseAntiAliasing(true);
options.setUseHighQualityRendering(true);
int pageCount = doc.getPageCount();
// if (pageCount > pageNum) {//生成前pageCount张
pageCount = pageNum;
}
List imageList = new ArrayList<>();
for (int i = 0; i < pageCount; i++) {
OutputStream output = new ByteArrayOutputStream();
options.setPageIndex(i);
doc.save(output, options);
ImageInputStream imageInputStream = javax.imageio.ImageIO.createImageInputStream(parse(output));
imageList.add(javax.imageio.ImageIO.read(imageInputStream));
}
return imageList;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
/**
* 合并任数量的图片成一张图片
*
* @param isHorizontal true代表水平合并,fasle代表垂直合并
* @param imgs 待合并的图片数组
* @return
* @throws IOException
*/
public static BufferedImage mergeImage(boolean isHorizontal, List imgs) throws IOException {
// 生成新图片
BufferedImage destImage = null;
// 计算新图片的长和高
int allw = 0, allh = 0, allwMax = 0, allhMax = 0;
// 获取总长、总宽、最长、最宽
for (int i = 0; i < imgs.size(); i++) {
BufferedImage img = imgs.get(i);
allw += img.getWidth();
if (imgs.size() != i + 1) {
allh += img.getHeight() + 5;
} else {
allh += img.getHeight();
}
if (img.getWidth() > allwMax) {
allwMax = img.getWidth();
}
if (img.getHeight() > allhMax) {
allhMax = img.getHeight();
}
}
// 创建新图片
if (isHorizontal) {
destImage = new BufferedImage(allw, allhMax, BufferedImage.TYPE_INT_RGB);
} else {
destImage = new BufferedImage(allwMax, allh, BufferedImage.TYPE_INT_RGB);
}
Graphics2D g2 = (Graphics2D) destImage.getGraphics();
g2.setBackground(Color.LIGHT_GRAY);
g2.clearRect(0, 0, allw, allh);
g2.setPaint(Color.RED);
// 合并所有子图片到新图片
int wx = 0, wy = 0;
for (int i = 0; i < imgs.size(); i++) {
BufferedImage img = imgs.get(i);
int w1 = img.getWidth();
int h1 = img.getHeight();
// 从图片中读取RGB
int[] ImageArrayOne = new int[w1 * h1];
ImageArrayOne = img.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中
if (isHorizontal) { // 水平方向合并
destImage.setRGB(wx, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
} else { // 垂直方向合并
destImage.setRGB(0, wy, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
}
wx += w1;
wy += h1 + 5;
}
return destImage;
}
//outputStream转inputStream
public static ByteArrayInputStream parse(OutputStream out) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos = (ByteArrayOutputStream) out;
}
}
excel转图片
public class ConvertToImage {
/**
* @Description: 验证aspose.cells组件是否授权:无授权的文件有水印标记
*/
public static boolean getLicense() {
boolean result = false;
try {
ClassPathResource resource = new ClassPathResource(“static/excelLicense.xml”);
InputStream inputStream = resource.getInputStream();
License aposeLic = new License();
aposeLic.setLicense(inputStream);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static ByteArrayOutputStream ConvertToImage(InputStream inputStream){
Workbook book = null;
if (!getLicense()) {
return null;
}
try {
book = new Workbook(inputStream);
Worksheet sheet = book.getWorksheets().get(0);
sheet.getPageSetup().setLeftMargin(-20);
sheet.getPageSetup().setRightMargin(0);
sheet.getPageSetup().setBottomMargin(0);
sheet.getPageSetup().setTopMargin(0);
ImageOrPrintOptions imgOptions = new ImageOrPrintOptions();
imgOptions.setImageFormat(ImageFormat.getJpeg());
imgOptions.setCellAutoFit(true);
imgOptions.setOnePagePerSheet(true);
// imgOptions.setDesiredSize(1000,800);
SheetRender render = new SheetRender(sheet, imgOptions);
//render.toImage(0, "D:\\SheetImage.jpg");
ByteArrayOutputStream output = new ByteArrayOutputStream();
render.toImage(0,output);
return output;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//outputStream转inputStream
public static ByteArrayInputStream parse(OutputStream out) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos = (ByteArrayOutputStream) out;
ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
return swapStream;
}
/**
@param filepath .xls或者.xlsx文件的路径
@parampicpath jpg或者png图片的路径
*/
public static void ConvertToImage (String filepath ,String picpath){
String dataDir = getDataDir(ConvertToImage.class);
Workbook book = null;
try {
//book = new Workbook(dataDir + "2018各项目情况.xlsx");
//读取文件
book = new Workbook(filepath);
// Get the first worksheet
Worksheet sheet = book.getWorksheets().get(0);
// 定义一个 ImageOrPrintOptions
ImageOrPrintOptions imgOptions = new ImageOrPrintOptions();
// 设置一个图片格式
imgOptions.setImageFormat(ImageFormat.getJpeg());
imgOptions.setCellAutoFit(true);
imgOptions.setOnePagePerSheet(true);
//imgOptions.setDefaultFont("200"); 默认字体大小
// Render the sheet with respect to specified image/print options
SheetRender render = new SheetRender(sheet, imgOptions);
// Render the image for the sheet
//render.toImage(0, dataDir + "SheetImage.jpg");
render.toImage(0, picpath);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getDataDir(Class c) {
File dir = new File(System.getProperty(“user.dir”));
System.out.println("shake" + dir.getAbsolutePath());
dir = new File(dir, "src");
dir = new File(dir, "main");
dir = new File(dir, "resources");
for (String s : c.getName().split("\\.")) {
dir = new File(dir, s);
}
if (dir.exists()) {
System.out.println("Using data directory: " + dir.toString());
} else {
dir.mkdirs();
System.out.println("Creating data directory: " + dir.toString());
}
return dir.toString() + File.separator;
}
// public static void main (String[] args ){
// ConvertToImage(InputStream in);
// }
}
当然如果没有license配置文件的话会有水印的,现在附上Word无水印的,excel的也适用,但是版本太高的话就要另觅它路了
Aspose.Total for JavaAspose.Words for JavaEnterprise20991231209912318bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=
在服务器上乱码还没解决,这是在网上查的:https://www.jianshu.com/p/8a769b4fcaf3
在这里附上必须要在服务器上的安装字体的原因https://docs.aspose.com/display/wordsnet/True+Type+Fonts#TrueTypeFonts-WhereAspose.WordsLooksforTrueTypeFontsonLinux
这个是aspose.Word论坛的地址 https://forum.aspose.com/c/words
aspose API地址 https://apireference.aspose.com
aspose-word的gitHub地址 https://github.com/aspose-words/Aspose.Words-for-Java/
乱码解决方式我在GitHub上提了一个issue,这个是地址 https://github.com/aspose-words/Aspose.Words-for-Java/issues/60
这个issue的意思是不用在服务器上安装字体直接把字体copy到你的项目里面然后在代码里面引入就行(还没测试,测试完会更新)
使用fontSettings。setFontFolder()这个要放绝对路径,本地可以,但是部署到服务器上就获取不到了,因为jar文件没法获取绝对路径,相对路径不起作用
//这个可以打印要文档都用到那些字体了
FontInfoCollection fontInfos = doc.getFontInfos();
// fontInfos.setEmbedTrueTypeFonts(true);
// fontInfos.setEmbedSystemFonts(false);
// fontInfos.setSaveSubsetFonts(false);
Iterator iterator = fontInfos.iterator();
while(iterator.hasNext()){
FontInfo next = (FontInfo) iterator.next();
String name = next.getName();
logger.info(name);
}
具体参考https://apireference.aspose.com/java/words/com.aspose.words/FontSettings
实现IWarningCallback,把实现的类放到doc中
doc.setWarningCallback(new WarnCallbackImpl());
doc.updatePageLayout()
doc.updateFields()
doc.getPageCount()
可以实现没有这个字体就会打印出来
参考地址https://docs.aspose.com/display/wordsjava/How+to+Receive+Notification+of+Missing+Fonts+and+Font+Substitution+during+Rendering
这个问题终于解决了,困扰了我好长时间
参考地址:https://apireference.aspose.com/java/words/com.aspose.words/MemoryFontSource
代码
FontSettings fontSettings = FontSettings.getDefaultInstance();
ClassPathResource resource = new ClassPathResource(“static/font/chinese/simsun.ttf”);
String path = resource.getPath();
logger.info(“自定义字体路径:”+path);
InputStream in = resource.getInputStream();
byte[] fontBytes = IOUtils.toByteArray(in);
doc.setFontSettings(fontSettings);
// byte[] fontBytes = Files.readAllBytes(Paths.get(path));
MemoryFontSource memoryFontSource = new MemoryFontSource(fontBytes,0);
doc.getFontSettings().setFontsSources(new FontSourceBase[]{memoryFontSource});