最近在研究企業文檔管理,這個是基本上所有企業都需要的軟體,當然也是有很多種解決方案。對于企業文檔來說,最基本的需求就是獨立存儲,共享。這種需求隻需要建立一個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中添加參數即可: