最近在研究企业文档管理,这个是基本上所有企业都需要的软件,当然也是有很多种解决方案。对于企业文档来说,最基本的需求就是独立存储,共享。这种需求只需要建立一个Windows共享文件夹或者架一个Samba服务器即可实现,无法做复杂的权限管理,统计等。另一种方案就是架一个Web应用,比如SharePoint,就可以实现。
既然是WEB应用,进一步的需求是能够在线查看文档,根据用户需求可能不允许下载,不允许打印文档。这一点微软的高级解决方案是使用RMS,能够设置每个用户的打开权限,是否打印等,要求必须是域内,而且只管理Office文件的权限,对txt,pdf就没办法了。另外一个解决方案是在线文档预览,用户在网页中查看文档内容,用户无需拿到原始文档,如果有权限的话,可以允许用户下载文档。这就就是百度文库,豆丁之类的网站的功能。下面来说说怎么实现。
这里的文档我们要看是什么格式,不同的格式有不同的转换方法。
对于Office文档(Word,Excel,PowerPoint),那么可以调用Office提供的COM接口,把文档另存为PDF。这个要求服务器上必须安装Office,同时要注意权限,不然很容易导致在本地调试时可以转换为PDF,但是一旦部署到服务器上去就不行。另外还需要注意的是,如果Office转换pdf时发生异常,可能导致Office的进程驻留在服务器,不断驻留Office进程会导致服务器资源耗尽。
这是Office文档转换为pdf的代码:
/// <summary>
/// 将word文档转换成PDF格式
/// </summary>
/// <param name="sourcePath"></param>
/// <param name="targetPath"></param>
/// <returns></returns>
public static bool ConvertWord2Pdf(string sourcePath, string targetPath)
{
bool result;
Word.WdExportFormat exportFormat= Word.WdExportFormat.wdExportFormatPDF;
object paramMissing = Type.Missing;
Word.Application wordApplication = new Word.Application();
Word.Document wordDocument = null;
try
{
object paramSourceDocPath = sourcePath;
string paramExportFilePath = targetPath;
Word.WdExportFormat paramExportFormat = exportFormat;
Word.WdExportOptimizeFor paramExportOptimizeFor =
Word.WdExportOptimizeFor.wdExportOptimizeForPrint;
Word.WdExportRange paramExportRange = Word.WdExportRange.wdExportAllDocument;
int paramStartPage = 0;
int paramEndPage = 0;
Word.WdExportItem paramExportItem = Word.WdExportItem.wdExportDocumentContent;
Word.WdExportCreateBookmarks paramCreateBookmarks =
Word.WdExportCreateBookmarks.wdExportCreateWordBookmarks;
wordDocument = wordApplication.Documents.Open(
ref paramSourceDocPath, ref paramMissing, ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing);
if (wordDocument != null)
wordDocument.ExportAsFixedFormat(paramExportFilePath,
paramExportFormat, false,
paramExportOptimizeFor, paramExportRange, paramStartPage,
paramEndPage, paramExportItem, true,
true, paramCreateBookmarks, true,
true, false,
ref paramMissing);
result = true;
}
finally
{
wordDocument.Close(ref paramMissing, ref paramMissing, ref paramMissing);
wordDocument = null;
}
if (wordApplication != null)
wordApplication.Quit(ref paramMissing, ref paramMissing, ref paramMissing);
wordApplication = null;
GC.Collect();
GC.WaitForPendingFinalizers();
return result;
}
/// 将excel文档转换成PDF格式
public static bool ConvertExcel2Pdf(string sourcePath, string targetPath)
object missing = Type.Missing;
Excel.XlFixedFormatType targetType= Excel.XlFixedFormatType.xlTypePDF;
Excel.Application application = null;
Excel.Workbook workBook = null;
application = new Excel.Application();
object target = targetPath;
workBook = application.Workbooks.Open(sourcePath, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing, missing, missing, missing);
workBook.ExportAsFixedFormat(targetType, target, Excel.XlFixedFormatQuality.xlQualityStandard, true, false, missing, missing, missing, missing);
catch
result = false;
if (workBook != null)
workBook.Close(true, missing, missing);
workBook = null;
if (application != null)
application.Quit();
application = null;
/// 将ppt文档转换成PDF格式
public static bool ConvertPowerPoint2Pdf(string sourcePath, string targetPath)
PowerPoint.PpSaveAsFileType targetFileType= PowerPoint.PpSaveAsFileType.ppSaveAsPDF;
PowerPoint.Application application = null;
PowerPoint.Presentation persentation = null;
application = new PowerPoint.Application();
persentation = application.Presentations.Open(sourcePath, MsoTriState.msoTrue, MsoTriState.msoFalse, MsoTriState.msoFalse);
persentation.SaveAs(targetPath, targetFileType, MsoTriState.msoTrue);
if (persentation != null)
persentation.Close();
persentation = null;
}
如果是文本需要转换为PDF,我们可以使用iTextSharp这个组件,对于纯文本,注意的是源文件中没有设置字体之类的,需要在转换成PDF时指定字体,否则对于中文可能由于没有设置字体而转换不出来。
/// 将Txt转换为PDF
/// </summary>
/// <param name="sourcePath"></param>
/// <param name="targetPath"></param>
/// <returns></returns>
public static bool ConvertText2Pdf(string sourcePath, string targetPath)
{
var text = FileHelper.ReadTextFile(sourcePath);
Document document = new Document(PageSize.A4);
try
{
//step 2:创建一个writer用于监听Document以及通过PDF-stream指向一个文件
PdfWriter.GetInstance(document, new FileStream(targetPath, FileMode.Create));
// step 3: 打开document
document.Open();
var f = GetFont();
// step 4: 添加一段话到document中
document.Add(new Paragraph(text, f));
}
catch (Exception ex)
return false;
finally
if (document.IsOpen())
// step 5: 关闭document
document.Close();
return true;
}
private static Font GetFont()
var fontPath = (string) ConfigurationManager.AppSettings["FontPath"];
if (string.IsNullOrEmpty(fontPath))//没有指定字体就用楷体
var fontName = "楷体";
if (!FontFactory.IsRegistered(fontName))
{
fontPath = Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\Fonts\simkai.ttf";
FontFactory.Register(fontPath);
}
return FontFactory.GetFont(fontName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
BaseFont bfChinese = BaseFont.CreateFont(fontPath,BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
Font fontChinese = new Font(bfChinese, 16f, Font.NORMAL);
return fontChinese;
}
HTML中包含的元素较多,比较复杂,主要有两种方法,一种是调用浏览器的接口,让浏览器把HTML打印为PDF,另外就是ITextSharp提供了专门的XML/HTML转换组件:XML Worker,这个已经独立出来,不包含在ITextSharp中,需要单独下载。
public static bool ConvertHtml2Pdf(string text, string pdfPath)
Document document = new Document(PageSize.A4);
try
{
PdfWriter.GetInstance(document, new FileStream(pdfPath, FileMode.Create));
document.Open();
var fontName = "楷体";
if (!FontFactory.IsRegistered(fontName))
{
var fontPath = Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\Fonts\simkai.ttf";
FontFactory.Register(fontPath);
}
var elements = iTextSharp.tool.xml.XMLWorkerHelper.ParseToElementList(text, @"body {
font-size: 16px;
color: #F00;
font-family: 楷体;
}");
//iTextSharp.text.
foreach (var element in elements)
document.Add(element);
}
}
catch (DocumentException de)
Console.Error.WriteLine(de.Message);
catch (IOException ioe)
Console.Error.WriteLine(ioe.Message);
document.Close();
return true;
}
以上都是转换成pdf的功能,在转换后,我们可以进一步使用ITextSharp对pdf进行加工,比较常见的添加水印功能。其实就是做一个淡淡的背景透明的图片,然后打开pdf文件,在每一页中画上水印图片即可。
/// 添加水印
/// <param name="inputPath">源PDF文件路径</param>
/// <param name="outputPath">加水印后的PDF路径</param>
/// <param name="watermarkPath">水印图片的路径</param>
/// <param name="error"></param>
public static bool AddWatermark(string inputPath, string outputPath, string watermarkPath, ref string error)
PdfReader pdfReader = new PdfReader(inputPath);
int numberOfPages = pdfReader.NumberOfPages;
FileStream outputStream = new FileStream(outputPath, FileMode.Create);
PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream);
PdfContentByte waterMarkContent;
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(watermarkPath);
image.SetAbsolutePosition(10, 10);
for (int i = 1; i <= numberOfPages; i++)
waterMarkContent = pdfStamper.GetUnderContent(i);
waterMarkContent.AddImage(image);
pdfStamper.Close();
pdfReader.Close();
outputStream.Close();
return true;
catch (Exception ex)
error = ex.StackTrace;
return false;
前面已经统一转换为pdf文档,接下来就是对pdf的在线预览。这个在以前是不现实的,现在有了HTML5,只要浏览器支持HTML5就可以使用pdf.js库,将服务器上的pdf文件转换成HTML5代码展示在浏览器上。另外还有一个解决方案是使用Flash,需要把pdf文件进一步转换为swf文件,然后由Flash播放器来播放这个文档。可惜Flash已经是一个过时即将淘汰的技术了,像iPad,iPhone就不支持Flash,所以使用HTML5才是更明智的选择。
pdf.js网站已经提供了库和示例,浏览页面是http://mozilla.github.io/pdf.js/web/viewer.html,我们要打开我们转换的文件,只需要在URL中添加参数即可: