前段时间项目中刚好有遇到这个需求,具体是实现将上传到服务端的附件进行不下载在线打印,打印时要进行预览。
一开始是想直接使用Java API的打印方法,具体实现时发现在启用后可以调出打印对话框,但打印机没有反应,查看了网上的很多方法,试了下还是不行,就放弃了。看下Java实现的代码:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaSizeName;
import javax.swing.JOptionPane;
public class PrintUtils {
public static void main(String[] args) {
FileInputStream textStream = null;
try {
textStream = new FileInputStream("C:\\CityLove.pdf");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//String printStr = "打印测试内容";// 获取需要打印的目标文本
if (textStream != null) // 当打印内容不为空时
{
// 指定打印输出格式
DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF;//SERVICE_FORMATTED.PRINTABLE
// 定位默认的打印服务
PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
// 创建打印作业
DocPrintJob job = printService.createPrintJob();
// 设置打印属性
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
// 设置纸张大小,也可以新建MediaSize类来自定义大小
pras.add(MediaSizeName.ISO_A4);
DocAttributeSet das = new HashDocAttributeSet();
// 指定打印内容
Doc doc = new SimpleDoc(textStream, flavor, das);
// 不显示打印对话框,直接进行打印工作
try {
job.print(doc, pras); // 进行每一页的具体打印操作
} catch (PrintException pe) {
pe.printStackTrace();
}
} else {
// 如果打印内容为空时,提示用户打印将取消
JOptionPane.showConfirmDialog(null,
"Sorry, Printer Job is Empty, Print Cancelled!",
"Empty", JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE);
}
}
}
之后就采用的POI方法装换文件,将word,Excel转成HTML页面,然后调用浏览器的打印功能。具体如下:
需要添加的maven依赖,对应版本,否则会报错
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>xdocreport</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.15</version><!--$NO-MVN-MAN-VER$-->
</dependency>
Java转换方法:
/**
* doc转HTML
*/
public String wordDocToHtml(String filePath) throws Exception {
InputStream input = new FileInputStream(filePath);
HWPFDocument wordDocument = new HWPFDocument(input);
WordToHtmlConverter wConverter =
new WordToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder()
.newDocument());
wConverter.setPicturesManager(new PicturesManager() {
@Override
public String savePicture(byte[] content, PictureType pictureType, String suggestedName,
float widthInches, float heightInches) {
return suggestedName;
}
});
wConverter.processDocument(wordDocument);
List list = wordDocument.getPicturesTable().getAllPictures();
if (list != null) {
for (int i = 0; i < list.size(); i++) {
Picture picture = (Picture) list.get(i);
picture.writeImageContent(new FileOutputStream(filePath + picture.suggestFullFileName()));
}
}
Document document = wConverter.getDocument();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
DOMSource domSource = new DOMSource(document);
StreamResult streamResult = new StreamResult(outputStream);
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer serializer = tFactory.newTransformer();
serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
serializer.setOutputProperty(OutputKeys.METHOD, "html");
serializer.transform(domSource, streamResult);
outputStream.close();
String content = new String(outputStream.toByteArray());
String newFilePath = UuidUtil.getTimeBasedUuid() + ".html";
File file = new File(filePath + newFilePath);
FileUtils.writeStringToFile(file, content, "utf-8");
return file.getName();
}
/**
* docx转HTML
*
* @throws Exception
*/
public String wordDocxToHtml(String filePath, HttpServletRequest request) throws Exception {
String sysFileString = getSysFilePath(request);
InputStream input = new FileInputStream(filePath);
XWPFDocument document = new XWPFDocument(input);
XHTMLOptions options = XHTMLOptions.create(); // 存放图片的文件夹
options.setExtractor(new FileImageExtractor(new File(sysFileString))); // html中图片的路径
options.URIResolver(new BasicURIResolver(sysFileString));
options.setIgnoreStylesIfUnused(false);
options.setFragment(true);
String newFilePath = UuidUtil.getTimeBasedUuid() + ".html";
File file = new File(filePath + newFilePath);
OutputStreamWriter outputStreamWriter =
new OutputStreamWriter(new FileOutputStream(file), "utf-8");
BufferedWriter bufferedOutputStream = new BufferedWriter(outputStreamWriter);
XHTMLConverter xhtmlConverter = (XHTMLConverter) XHTMLConverter.getInstance();
xhtmlConverter.convert(document, bufferedOutputStream, options);
if (outputStreamWriter != null) {
outputStreamWriter.close();
}
return file.getName();
}
/**
* Excel转HTML
*
* @throws Exception
*/
public String excelToHtml(String filePath, String suffix) throws Exception {
InputStream input = new FileInputStream(filePath);
HSSFWorkbook excelBook = null;
if (suffix.equals("xlsx")) {
// 将07版转化为03版
Xssf2HssfUtil xlsx2xls = new Xssf2HssfUtil();
XSSFWorkbook xSSFWorkbook = new XSSFWorkbook(input);
excelBook = new HSSFWorkbook();
xlsx2xls.transformXSSF(xSSFWorkbook, excelBook);
} else {
excelBook = new HSSFWorkbook(input);
}
ExcelToHtmlConverter eHtmlConverter =
new ExcelToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder()
.newDocument());
int index = excelBook.getActiveSheetIndex();
String sheetName = "";
for (int i = 0; i < index + 1; i++) {
// 设置字体
HSSFFont font = excelBook.getFontAt((short) i);
font.setCharSet(HSSFFont.DEFAULT_CHARSET);
font.setFontHeightInPoints((short) 8);// 更改默认字体大小
font.setFontName("黑体");// 更改字体格式
font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);// 非粗体显示
// 去掉Excel头
eHtmlConverter.setOutputColumnHeaders(false);
// 去掉Excel行号
eHtmlConverter.setOutputRowNumbers(false);
// 去掉表名
sheetName = sheetName + " ";
excelBook.setSheetName(i, sheetName + " ");
}
eHtmlConverter.processWorkbook(excelBook);
List pics = excelBook.getAllPictures();
if (pics != null) {
for (int i = 0; i < pics.size(); i++) {
Picture pic = (Picture) pics.get(i);
pic.writeImageContent(new FileOutputStream(filePath + pic.suggestFullFileName()));
}
}
Document htmlDocument = eHtmlConverter.getDocument();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
DOMSource domSource = new DOMSource(htmlDocument);
StreamResult streamResult = new StreamResult(outStream);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer serializer = tf.newTransformer();
serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
serializer.setOutputProperty(OutputKeys.METHOD, "html");
serializer.transform(domSource, streamResult);
outStream.close();
String content = new String(outStream.toByteArray());
String newFilePath = UuidUtil.getTimeBasedUuid() + ".html";
File file = new File(filePath + newFilePath);
FileUtils.writeStringToFile(file, content, "utf-8");
return file.getName();
}
最终虽然大致实现了功能,但是还有很多问题,在文件转换时,有很多样式没法保存,比如说有的下划线丢失了,文档的对齐格式跑偏。这几个问题有尝试去修改,在网上也搜了很多,没有找到解决方法。个人觉得还是把文件转成PDF格式,再去进行操作可能会更好一点。
希望分享对大家有所帮助,欢迎留言改进。