index.aspx代码(<%@ Page Language="C#" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="Report_index" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
<title>运营报告</title>
<script src="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/build/pdf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/build/pdf.worker.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<style>
* {
margin: 0;
padding: 0;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
line-height: 1.6;
}
.container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
}
.page-header {
padding-bottom: 0.5rem;
margin: 1.5rem 0 1rem;
border-bottom: 1px solid #eee;
color: #333;
}
h2, h3 {
margin-top: 1rem;
margin-bottom: 0.75rem;
font-weight: 500;
line-height: 1.1;
}
h2 {
font-size: clamp(1.5rem, 3vw, 2rem);
}
h3 {
font-size: clamp(1.2rem, 2.5vw, 1.6rem);
}
.pdf-list-container {
margin-top: 1.5rem;
}
.pdf-list-item {
cursor: pointer;
padding: 1rem;
margin-bottom: 0.5rem;
border: 1px solid #eee;
border-radius: 4px;
transition: all 0.2s ease;
background-color: #fff;
font-size: clamp(1rem, 2vw, 1.2rem);
display: flex;
align-items: center;
justify-content: space-between;
}
.pdf-list-item:hover:not(.text-muted) {
background-color: #f5f5f5;
border-color: #ccc;
transform: translateY(-1px);
}
.pdf-list-item.active {
background-color: #e3f2fd;
border-color: #2196f3;
font-weight: 500;
}
.pdf-list-item.text-muted {
color: #777;
cursor: not-allowed;
background-color: #f9f9f9;
}
#loadingTip {
min-height: calc(100vh - 200px);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
color: #666;
}
.spinner {
margin-right: 10px;
width: 30px;
height: 30px;
border: 3px solid rgba(0,0,0,.1);
border-radius: 50%;
border-top-color: #337ab7;
animation: spin 1s ease-in-out infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.error-message {
color: #d9534f;
text-align: center;
padding: 20px;
line-height: 1.8;
}
#timeoutTip {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255,255,255,0.85);
align-items: center;
justify-content: center;
z-index: 10;
flex-direction: column;
}
.timeout-retry-btn {
margin-top: 10px;
padding: 8px 16px;
border: 1px solid #2196f3;
border-radius: 4px;
background: #fff;
color: #2196f3;
cursor: pointer;
transition: all 0.2s;
font-size: 1rem;
}
.timeout-retry-btn:hover {
background: #e3f2fd;
}
.label {
display: inline-block;
padding: .2em .6em .3em;
font-size: 75%;
font-weight: 700;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25em;
margin-left: 10px;
}
.label-danger {
background-color: #d9534f;
}
.file-icon {
margin-right: 8px;
}
.progress-container {
width: 100%;
height: 4px;
background-color: #f1f1f1;
position: absolute;
top: 0;
left: 0;
z-index: 15;
display: none;
}
.progress-bar {
height: 100%;
background-color: #2196f3;
width: 0%;
transition: width 0.3s ease;
}
@media (max-width: 768px) {
.pdf-list-item {
padding: 0.75rem;
flex-direction: column;
align-items: flex-start;
}
.label {
margin-left: 0;
margin-top: 0.5rem;
align-self: flex-start;
}
}
/* 双击放大相关样式 */
.zoom-target-highlight {
position: absolute;
border: 2px solid #2196f3;
border-radius: 4px;
pointer-events: none;
z-index: 10;
animation: pulse 0.5s ease-in-out;
}
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.1); opacity: 0.8; }
100% { transform: scale(1); opacity: 0; }
}
/* 占位容器:固定原列表容器的空间 */
.pdf-list-placeholder {
height: 200px;
visibility: hidden;
}
/* 原列表容器 */
.pdf-list-container {
position: absolute;
left: 0;
top: -9999px;
opacity: 0;
pointer-events: none;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div class="container">
<div id="loadingTip">
<div class="spinner"></div>
<span>正在加载,请稍候...</span>
</div>
<div id="pdfPreviewContainer">
<div class="progress-container">
<div class="progress-bar" id="progressBar"></div>
</div>
<div id="pdfContainer"></div>
<div id="timeoutTip" class="error-message">
<span>❌</span>
<br/>加载超时,请检查网络或尝试重新点击
</div>
</div>
<div class="pdf-list-placeholder"></div>
<div class="pdf-list-container" style="padding:10px;display: none;">
<h3 >历史维护报告</h3>
<div id="pdfList" style="width: 100%; max-width: 700px; padding-bottom: 20px" >
<asp:Repeater ID="rptPdfList" runat="server">
<ItemTemplate>
<div class="pdf-list-item "
data-pdf-url="<%# GetProxyUrl((Eval("PdfUrl").ToString()),Convert.ToInt32(Eval("pid"))) %>"
data-pdf-name="<%# Eval("PdfName") %>"
data-name="<%# Eval("Name") %>"
data-is-valid="True"
>
<span><i class="fa fa-file-pdf-o file-icon"></i><%# Eval("PdfName") %></span>
</div>
</ItemTemplate>
</asp:Repeater>
</div>
</div>
</div>
</form>
<script>
let pdfDoc = null;
let zoom = 1.0;
let isRendering = false;
let loadTimer = null;
let baseScale = 1.0;
let renderedPages = 0;
let totalPages = 0;
let currentPdfUrl = null;
let lastClickTime = 0;
let clickTimeout = null;
let isZoomed = false;
let originalZoom = 1.0;
let lastDoubleClickData = null;
let pdfContainer, loadingTip, pdfPreviewContainer;
let timeoutTip, progressBar, progressContainer;
document.addEventListener('DOMContentLoaded', function () {
pdfContainer = document.getElementById('pdfContainer');
loadingTip = document.getElementById('loadingTip');
pdfPreviewContainer = document.getElementById('pdfPreviewContainer');
timeoutTip = document.getElementById('timeoutTip');
progressBar = document.getElementById('progressBar');
progressContainer = document.querySelector('.progress-container');
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/build/pdf.worker.min.js';
initDefaultPdf();
setupPdfListClickHandlers();
setupDoubleClickZoom();
document.addEventListener('keydown', function (e) {
if ((e.ctrlKey && (e.key === 's' || e.key === 'p')) || e.key === 'F12') {
e.preventDefault();
return false;
}
});
// 窗口大小变化时重新渲染
let resizeTimeout;
window.addEventListener('resize', function () {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (pdfDoc && pdfContainer) {
calculateBaseScale();
renderAllPages().then(() => {
if (lastDoubleClickData) {
centerClickPoint(lastDoubleClickData);
}
});
}
}, 200);
});
// 显示PDF列表容器
const pdfListContainer = document.querySelector('.pdf-list-container');
if (pdfListContainer) {
pdfListContainer.style.display = 'block';
}
});
// 设置双击缩放功能
function setupDoubleClickZoom() {
if (!pdfContainer) return;
pdfContainer.addEventListener('click', function (e) {
const now = Date.now();
const DOUBLE_CLICK_THRESHOLD = 300;
if (clickTimeout) {
clearTimeout(clickTimeout);
}
if (now - lastClickTime < DOUBLE_CLICK_THRESHOLD) {
handleDoubleClickZoom(e);
lastClickTime = 0;
} else {
lastClickTime = now;
clickTimeout = setTimeout(() => {
lastClickTime = 0;
}, DOUBLE_CLICK_THRESHOLD);
}
});
}
// 处理双击放大/还原
function handleDoubleClickZoom(event) {
if (!pdfDoc || !pdfContainer) return;
event.preventDefault();
const containerRect = pdfContainer.getBoundingClientRect();
const scrollLeft = pdfContainer.scrollLeft;
const scrollTop = pdfContainer.scrollTop;
// 计算点击位置(考虑滚动偏移)
const clientX = event.clientX;
const clientY = event.clientY;
const clickX = clientX - containerRect.left + scrollLeft;
const clickY = clientY - containerRect.top + scrollTop;
// 创建视觉反馈
const highlight = document.createElement('div');
highlight.className = 'zoom-target-highlight';
highlight.style.width = '80px';
highlight.style.height = '80px';
highlight.style.left = `${clientX - containerRect.left - 40}px`;
highlight.style.top = `${clientY - containerRect.top - 40}px`;
pdfContainer.appendChild(highlight);
setTimeout(() => {
if (pdfContainer.contains(highlight)) {
pdfContainer.removeChild(highlight);
}
}, 500);
// 确定点击的页码和相对位置
const pageData = getClickedPageAndPosition(clickX, clickY);
if (!pageData) return;
// 保存双击数据
lastDoubleClickData = {
targetPageNum: pageData.pageNum,
ratioX: pageData.ratioX,
ratioY: pageData.ratioY
};
// 切换缩放状态
if (!isZoomed) {
// 放大操作
originalZoom = zoom;
zoom *= 1.5;
isZoomed = true;
} else {
// 还原操作
zoom = originalZoom;
isZoomed = false;
}
renderAllPages();
}
// 获取点击的页码和相对位置 - 完全重写版本
function getClickedPageAndPosition(clickX, clickY) {
if (!pdfContainer) return null;
const pageContainers = pdfContainer.querySelectorAll('.pdf-page-container');
for (let i = 0; i < pageContainers.length; i++) {
const page = pageContainers[i];
const pageRect = page.getBoundingClientRect();
const containerRect = pdfContainer.getBoundingClientRect();
// 计算页面在容器内的绝对位置(考虑滚动)
const pageAbsoluteTop = page.offsetTop;
const pageAbsoluteBottom = pageAbsoluteTop + page.offsetHeight;
const pageAbsoluteLeft = page.offsetLeft;
const pageAbsoluteRight = pageAbsoluteLeft + page.offsetWidth;
// 检查点击是否在当前页面范围内
if (clickY >= pageAbsoluteTop && clickY <= pageAbsoluteBottom &&
clickX >= pageAbsoluteLeft && clickX <= pageAbsoluteRight) {
// 计算在页面内的相对位置
const relativeX = clickX - pageAbsoluteLeft;
const relativeY = clickY - pageAbsoluteTop;
return {
pageNum: i + 1,
ratioX: Math.max(0, Math.min(1, relativeX / page.offsetWidth)),
ratioY: Math.max(0, Math.min(1, relativeY / page.offsetHeight))
};
}
}
// 如果没有找到精确匹配的页面,返回第一个页面中心
if (pageContainers.length > 0) {
return {
pageNum: 1,
ratioX: 0.5,
ratioY: 0.5
};
}
return null;
}
// 将点击点居中显示 - 完全重写版本
function centerClickPoint(doubleClickData) {
if (!pdfContainer || !doubleClickData) return;
const { targetPageNum, ratioX, ratioY } = doubleClickData;
// 获取所有页面容器
const pageContainers = pdfContainer.querySelectorAll('.pdf-page-container');
if (pageContainers.length === 0) return;
// 找到目标页面
const targetPage = pageContainers[targetPageNum - 1];
if (!targetPage) return;
// 计算目标页面的绝对位置
const pageTop = targetPage.offsetTop;
const pageLeft = targetPage.offsetLeft;
const pageWidth = targetPage.offsetWidth;
const pageHeight = targetPage.offsetHeight;
// 根据比例计算点击点在页面内的位置
const pointInPageX = pageWidth * ratioX;
const pointInPageY = pageHeight * ratioY;
// 计算点击点在容器内的绝对位置
const absoluteX = pageLeft + pointInPageX;
const absoluteY = pageTop + pointInPageY;
// 计算需要滚动到的位置,使点击点居中
const containerWidth = pdfContainer.clientWidth;
const containerHeight = pdfContainer.clientHeight;
const scrollToX = Math.max(0, Math.min(absoluteX - containerWidth / 2, pdfContainer.scrollWidth - containerWidth));
const scrollToY = Math.max(0, Math.min(absoluteY - containerHeight / 2, pdfContainer.scrollHeight - containerHeight));
// 使用requestAnimationFrame确保在渲染完成后执行滚动
requestAnimationFrame(() => {
pdfContainer.scrollTo({
left: scrollToX,
top: scrollToY,
behavior: 'smooth'
});
});
}
// 设置PDF列表项的点击事件处理
function setupPdfListClickHandlers() {
const pdfList = document.getElementById('pdfList');
if (!pdfList) return;
pdfList.addEventListener('click', function (e) {
const listItem = e.target.closest('.pdf-list-item');
if (!listItem) return;
e.preventDefault();
e.stopPropagation();
const isValid = listItem.getAttribute('data-is-valid') === 'True';
if (!isValid) {
alert('当前文件链接无效,无法预览');
return;
}
const pdfUrl = listItem.getAttribute('data-pdf-url');
if (listItem.classList.contains('active') && pdfDoc && pdfUrl === currentPdfUrl) {
return;
}
document.querySelectorAll('.pdf-list-item').forEach(li => li.classList.remove('active'));
listItem.classList.add('active');
// 重置缩放状态
zoom = 1.0;
isZoomed = false;
originalZoom = 1.0;
lastDoubleClickData = null;
const pdfName = listItem.getAttribute('data-pdf-name');
const name = listItem.getAttribute('data-name');
loadPdf(pdfUrl, pdfName, name);
});
}
// 初始化默认加载第一个有效PDF
function initDefaultPdf() {
let defaultItem = document.querySelector('.pdf-list-item[data-is-valid="True"]');
if (!defaultItem) {
defaultItem = document.querySelector('.pdf-list-item');
}
if (defaultItem) {
const pdfUrl = defaultItem.getAttribute('data-pdf-url');
const pdfName = defaultItem.getAttribute('data-pdf-name');
const name = defaultItem.getAttribute('data-name');
defaultItem.classList.add('active');
loadPdf(pdfUrl, pdfName, name);
} else if (loadingTip) {
loadingTip.innerHTML = '<div class="error-message">没有找到可预览的PDF文件</div>';
}
}
// 重新加载当前PDF
function reloadCurrentPdf() {
if (currentPdfUrl) {
const activeItem = document.querySelector('.pdf-list-item.active');
if (activeItem) {
const pdfName = activeItem.getAttribute('data-pdf-name');
const name = activeItem.getAttribute('data-name');
loadPdf(currentPdfUrl, pdfName, name);
}
}
}
// 加载PDF文件
function loadPdf(pdfUrl, pdfName, name) {
if (!pdfPreviewContainer || !loadingTip || !timeoutTip || !progressContainer || !progressBar) {
console.error('DOM元素未准备好');
return;
}
currentPdfUrl = pdfUrl;
// 重置状态
pdfDoc = null;
baseScale = 1.0;
renderedPages = 0;
totalPages = 0;
isZoomed = false;
originalZoom = 1.0;
lastDoubleClickData = null;
// 更新UI
loadingTip.style.display = 'flex';
pdfPreviewContainer.style.display = 'block';
timeoutTip.style.display = 'none';
progressContainer.style.display = 'none';
progressBar.style.width = '0%';
document.title = pdfName || '运营报告';
clearTimeout(loadTimer);
// 微信环境防缓存
let urlToLoad = pdfUrl;
const isWeChat = /MicroMessenger/i.test(navigator.userAgent);
if (isWeChat) {
urlToLoad += (urlToLoad.includes('?') ? '&' : '?') + 't=' + new Date().getTime();
}
// 加载PDF
const loadingTask = pdfjsLib.getDocument({
url: urlToLoad,
cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/cmaps/',
cMapPacked: true,
withCredentials: false,
timeout: 20000
});
loadingTask.promise.then(function (pdfDoc_) {
pdfDoc = pdfDoc_;
totalPages = pdfDoc.numPages;
calculateBaseScale().then(() => {
if (loadingTip) loadingTip.style.display = 'none';
if (progressContainer) progressContainer.style.display = 'block';
renderAllPages();
clearTimeout(loadTimer);
});
}).catch(function (error) {
console.error('Error loading PDF:', error);
if (loadingTip) {
loadingTip.innerHTML = `
<div class="error-message">
<span>❌</span>
<br>加载失败,请检查文件链接或网络
<br><button class="timeout-retry-btn" onclick="reloadCurrentPdf()">点击重试</button>
</div>
`;
}
if (pdfPreviewContainer) pdfPreviewContainer.style.display = 'none';
clearTimeout(loadTimer);
});
// 加载超时处理
loadTimer = setTimeout(() => {
if (!pdfDoc) {
if (loadingTip) loadingTip.style.display = 'none';
if (timeoutTip) {
timeoutTip.style.display = 'flex';
timeoutTip.innerHTML = `
<span>❌</span>
<br/>PDF加载超时,请检查网络或尝试重新点击
<br><button class="timeout-retry-btn" onclick="reloadCurrentPdf()">点击重试</button>
`;
}
}
}, 15000);
}
function calculateBaseScale() {
return new Promise((resolve) => {
if (!pdfDoc || !pdfContainer) {
baseScale = 1.0;
resolve();
return;
}
const containerWidth = pdfContainer.clientWidth;
if (containerWidth <= 0) {
baseScale = 1.0;
resolve();
return;
}
pdfDoc.getPage(1).then(function (page) {
const viewport = page.getViewport({ scale: 1 });
baseScale = containerWidth / viewport.width;
resolve();
}).catch(() => {
baseScale = 1.0;
resolve();
});
});
}
// 渲染所有页面
function renderAllPages() {
return new Promise((resolve) => {
if (!pdfDoc || isRendering || !pdfContainer) {
resolve();
return;
}
isRendering = true;
renderedPages = 0;
pdfContainer.innerHTML = '';
const renderPage = (pageNum) => {
if (pageNum > pdfDoc.numPages) {
isRendering = false;
// 所有页面渲染完成后,执行双击定位
setTimeout(() => {
if (lastDoubleClickData) {
centerClickPoint(lastDoubleClickData);
}
resolve();
}, 100);
return;
}
pdfDoc.getPage(pageNum).then(function (page) {
const finalScale = baseScale * zoom;
const viewport = page.getViewport({ scale: finalScale });
// 适配设备像素比
const dpr = window.devicePixelRatio || 1;
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = Math.floor(viewport.width * dpr);
canvas.height = Math.floor(viewport.height * dpr);
canvas.style.width = `${viewport.width}px`;
canvas.style.height = `${viewport.height}px`;
context.setTransform(dpr, 0, 0, dpr, 0, 0);
const pageContainer = document.createElement('div');
pageContainer.className = 'pdf-page-container';
pageContainer.setAttribute('data-page-number', pageNum);
pageContainer.style.marginBottom = '10px';
pageContainer.appendChild(canvas);
if (pdfContainer.isConnected) {
pdfContainer.appendChild(pageContainer);
} else {
console.error('pdfContainer不在DOM中');
isRendering = false;
resolve();
return;
}
// 渲染页面
const renderContext = { canvasContext: context, viewport: viewport };
const renderTask = page.render(renderContext);
renderTask.promise.then(function () {
renderedPages++;
if (progressBar) {
const progress = (renderedPages / totalPages) * 100;
progressBar.style.width = `${progress}%`;
}
if (renderedPages === totalPages && progressContainer) {
setTimeout(() => {
progressContainer.style.display = 'none';
}, 500);
}
// 渲染下一页
renderPage(pageNum + 1);
}).catch(function (error) {
console.error(`渲染第${pageNum}页失败:`, error);
renderedPages++;
renderPage(pageNum + 1);
});
}).catch(function (error) {
console.error(`获取第${pageNum}页失败:`, error);
renderPage(pageNum + 1);
});
};
renderPage(1);
});
}
</script>
</body>
</html>),index.aspx.cs代码(using LiangCeLib.DAL;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Utils;
public partial class Report_index : System.Web.UI.Page
{
ProjectDocumentsDal dalproject = new ProjectDocumentsDal();
CustomerAccountsDal dalAccount = new CustomerAccountsDal();
public class PdfFileModel
{
public int pid { get; set; }
public string PdfName { get; set; }
public string PdfUrl { get; set; }
public string Name { get; set; }
public bool IsValid { get; set; } // 标记PDF是否有效
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var id = SL.GetQueryIntValue("id");
if (id == 0)
{
id = 1;
}
BindPdfList(id);
}
if (!string.IsNullOrEmpty(Request.QueryString["pdfUrl"]))
{
ProxyPdfFile();
Response.End();
}
}
private void BindPdfList(int id)
{
var model = dalproject.GetPDF(id);
// 确保列表按创建时间倒序排列(最新的在前面)
List<PdfFileModel> pdfList = model
.OrderByDescending(item => item.CREATETIME)
.Select(item => new PdfFileModel
{
pid = item.pid,
PdfName = FormatReportTitle(item.projectName, item.CREATETIME, item.PDFILEURL),
PdfUrl = "http://www.black-jet.cn" + item.PDFILEURL,
Name = item.projectName,
IsValid = IsValidPdfUrl("http://www.black-jet.cn" + item.PDFILEURL)
}).ToList();
rptPdfList.DataSource = pdfList;
rptPdfList.DataBind();
}
protected string GetProxyUrl(string originalUrl, int pid)
{
string encodedUrl = HttpUtility.UrlEncode(originalUrl);
string currentPagePath = HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath + "?id=" + pid;
string absolutePagePath = VirtualPathUtility.ToAbsolute(currentPagePath);
return absolutePagePath + "&pdfUrl=" + encodedUrl;
}
private void ProxyPdfFile()
{
try
{
string encodedPdfUrl = Request.QueryString["pdfUrl"];
string pdfUrl = HttpUtility.UrlDecode(encodedPdfUrl);
if (string.IsNullOrEmpty(pdfUrl))
{
Response.StatusCode = 400;
Response.Write("无效的PDF链接,请检查链接格式");
return;
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(pdfUrl);
request.Method = "GET";
request.Timeout = 20000;
request.UserAgent = "Mozilla/5.0 (Linux; Android 10; MI 9 SE Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/86.0.4240.99 XWEB/3263 MMWEBSDK/20220401 Mobile Safari/537.36 MMWEBID/6505 MicroMessenger/8.0.24.2120(0x28001857) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64";
request.Accept = "application/pdf,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
request.AllowAutoRedirect = true;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
if (!response.ContentType.Contains("application/pdf") &&
!response.ContentType.Contains("application/octet-stream"))
{
Response.StatusCode = 415;
Response.Write("文件不是有效的PDF格式,当前类型:" + response.ContentType);
return;
}
Response.ContentType = "application/pdf";
string fileName = System.IO.Path.GetFileName(pdfUrl);
Response.AddHeader("Content-Disposition", "inline; filename=\"" + fileName + "\"");
Response.AddHeader("Content-Length", response.ContentLength.ToString());
Response.AddHeader("Cache-Control", "public, must-revalidate, max-age=0");
Response.AddHeader("Pragma", "public");
Response.AddHeader("X-Content-Type-Options", "nosniff");
Response.AddHeader("Accept-Ranges", "bytes");
Response.AddHeader("X-Download-Options", "noopen");
using (var stream = response.GetResponseStream())
{
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
Response.OutputStream.Write(buffer, 0, bytesRead);
}
}
Response.Flush();
}
}
catch (WebException ex)
{
Response.StatusCode = 500;
Response.Write("PDF加载失败:" + ex.Message);
if (ex.Response != null)
{
Response.Write("(HTTP状态码:" + ((HttpWebResponse)ex.Response).StatusCode + ")");
}
}
catch (Exception ex)
{
Response.StatusCode = 500;
Response.Write("服务器处理错误:" + ex.Message);
}
}
protected bool IsValidPdfUrl(string pdfUrl)
{
try
{
if (!Uri.IsWellFormedUriString(pdfUrl, UriKind.Absolute))
return false;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(pdfUrl);
try
{
request.Method = "HEAD";
request.Timeout = 5000;
request.UserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
return response.StatusCode == HttpStatusCode.OK &&
(response.ContentType.Contains("application/pdf") ||
response.ContentType.Contains("application/octet-stream"));
}
}
catch
{
request.Method = "GET";
request.Timeout = 5000;
request.AddRange(0, 99);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
return response.StatusCode == HttpStatusCode.PartialContent ||
response.StatusCode == HttpStatusCode.OK;
}
}
}
catch
{
return false;
}
}
private string FormatReportTitle(string companyName, DateTime dateString, string PDFILEURL)
{
try
{
DateTime reportDate = dateString;
int year = reportDate.Year;
return companyName + "技术运营报告(" + (ExtractMonthFromFilePath(PDFILEURL)) + ")- " + year;
}
catch (Exception ex)
{
Console.WriteLine("日期格式错误: " + ex.Message);
return companyName + "技术运营报告";
}
}
private string ExtractMonthFromFilePath(string filePath)
{
if (string.IsNullOrEmpty(filePath))
return null;
Match match = Regex.Match(filePath, @"\d+月");
if (match.Success)
{
return match.Value;
}
Match dateMatch = Regex.Match(filePath, @"\d{8}");
if (dateMatch.Success && dateMatch.Value.Length == 8)
{
string monthPart = dateMatch.Value.Substring(4, 2);
return int.Parse(monthPart) + "月";
}
return null;
}
}),双击放大,双击点显示在页面中间,没有问题。但双击还原缩小后没有显示将双击点显示在页面中间。修改以上代码,实现双击还原后,双击点保持在页面中心。生成完整代码
最新发布